diff options
Diffstat (limited to 'drivers')
39 files changed, 25102 insertions, 0 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 55205c8d2318..447d8e68887a 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -69,6 +69,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ | |||
| 69 | obj-$(CONFIG_MMC) += mmc/ | 69 | obj-$(CONFIG_MMC) += mmc/ |
| 70 | obj-$(CONFIG_NEW_LEDS) += leds/ | 70 | obj-$(CONFIG_NEW_LEDS) += leds/ |
| 71 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 71 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
| 72 | obj-$(CONFIG_IPATH_CORE) += infiniband/ | ||
| 72 | obj-$(CONFIG_SGI_SN) += sn/ | 73 | obj-$(CONFIG_SGI_SN) += sn/ |
| 73 | obj-y += firmware/ | 74 | obj-y += firmware/ |
| 74 | obj-$(CONFIG_CRYPTO) += crypto/ | 75 | obj-$(CONFIG_CRYPTO) += crypto/ |
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index bdf0891a92dd..afc612b8577d 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig | |||
| @@ -30,6 +30,7 @@ config INFINIBAND_USER_ACCESS | |||
| 30 | <http://www.openib.org>. | 30 | <http://www.openib.org>. |
| 31 | 31 | ||
| 32 | source "drivers/infiniband/hw/mthca/Kconfig" | 32 | source "drivers/infiniband/hw/mthca/Kconfig" |
| 33 | source "drivers/infiniband/hw/ipath/Kconfig" | ||
| 33 | 34 | ||
| 34 | source "drivers/infiniband/ulp/ipoib/Kconfig" | 35 | source "drivers/infiniband/ulp/ipoib/Kconfig" |
| 35 | 36 | ||
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile index a43fb34cca94..eea27322a22d 100644 --- a/drivers/infiniband/Makefile +++ b/drivers/infiniband/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | obj-$(CONFIG_INFINIBAND) += core/ | 1 | obj-$(CONFIG_INFINIBAND) += core/ |
| 2 | obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ | 2 | obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ |
| 3 | obj-$(CONFIG_IPATH_CORE) += hw/ipath/ | ||
| 3 | obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ | 4 | obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ |
| 4 | obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ | 5 | obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ |
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig new file mode 100644 index 000000000000..9ea67c409b6d --- /dev/null +++ b/drivers/infiniband/hw/ipath/Kconfig | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | config IPATH_CORE | ||
| 2 | tristate "PathScale InfiniPath Driver" | ||
| 3 | depends on 64BIT && PCI_MSI && NET | ||
| 4 | ---help--- | ||
| 5 | This is a low-level driver for PathScale InfiniPath host channel | ||
| 6 | adapters (HCAs) based on the HT-400 and PE-800 chips. | ||
| 7 | |||
| 8 | config INFINIBAND_IPATH | ||
| 9 | tristate "PathScale InfiniPath Verbs Driver" | ||
| 10 | depends on IPATH_CORE && INFINIBAND | ||
| 11 | ---help--- | ||
| 12 | This is a driver that provides InfiniBand verbs support for | ||
| 13 | PathScale InfiniPath host channel adapters (HCAs). This | ||
| 14 | allows these devices to be used with both kernel upper level | ||
| 15 | protocols such as IP-over-InfiniBand as well as with userspace | ||
| 16 | applications (in conjunction with InfiniBand userspace access). | ||
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile new file mode 100644 index 000000000000..b4d084abfd22 --- /dev/null +++ b/drivers/infiniband/hw/ipath/Makefile | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | EXTRA_CFLAGS += -DIPATH_IDSTR='"PathScale kernel.org driver"' \ | ||
| 2 | -DIPATH_KERN_TYPE=0 | ||
| 3 | |||
| 4 | obj-$(CONFIG_IPATH_CORE) += ipath_core.o | ||
| 5 | obj-$(CONFIG_INFINIBAND_IPATH) += ib_ipath.o | ||
| 6 | |||
| 7 | ipath_core-y := \ | ||
| 8 | ipath_diag.o \ | ||
| 9 | ipath_driver.o \ | ||
| 10 | ipath_eeprom.o \ | ||
| 11 | ipath_file_ops.o \ | ||
| 12 | ipath_fs.o \ | ||
| 13 | ipath_ht400.o \ | ||
| 14 | ipath_init_chip.o \ | ||
| 15 | ipath_intr.o \ | ||
| 16 | ipath_layer.o \ | ||
| 17 | ipath_pe800.o \ | ||
| 18 | ipath_stats.o \ | ||
| 19 | ipath_sysfs.o \ | ||
| 20 | ipath_user_pages.o | ||
| 21 | |||
| 22 | ipath_core-$(CONFIG_X86_64) += ipath_wc_x86_64.o | ||
| 23 | |||
| 24 | ib_ipath-y := \ | ||
| 25 | ipath_cq.o \ | ||
| 26 | ipath_keys.o \ | ||
| 27 | ipath_mad.o \ | ||
| 28 | ipath_mr.o \ | ||
| 29 | ipath_qp.o \ | ||
| 30 | ipath_rc.o \ | ||
| 31 | ipath_ruc.o \ | ||
| 32 | ipath_srq.o \ | ||
| 33 | ipath_uc.o \ | ||
| 34 | ipath_ud.o \ | ||
| 35 | ipath_verbs.o \ | ||
| 36 | ipath_verbs_mcast.o | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h new file mode 100644 index 000000000000..48a55247b832 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_common.h | |||
| @@ -0,0 +1,616 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _IPATH_COMMON_H | ||
| 34 | #define _IPATH_COMMON_H | ||
| 35 | |||
| 36 | /* | ||
| 37 | * This file contains defines, structures, etc. that are used | ||
| 38 | * to communicate between kernel and user code. | ||
| 39 | */ | ||
| 40 | |||
| 41 | /* This is the IEEE-assigned OUI for PathScale, Inc. */ | ||
| 42 | #define IPATH_SRC_OUI_1 0x00 | ||
| 43 | #define IPATH_SRC_OUI_2 0x11 | ||
| 44 | #define IPATH_SRC_OUI_3 0x75 | ||
| 45 | |||
| 46 | /* version of protocol header (known to chip also). In the long run, | ||
| 47 | * we should be able to generate and accept a range of version numbers; | ||
| 48 | * for now we only accept one, and it's compiled in. | ||
| 49 | */ | ||
| 50 | #define IPS_PROTO_VERSION 2 | ||
| 51 | |||
| 52 | /* | ||
| 53 | * These are compile time constants that you may want to enable or disable | ||
| 54 | * if you are trying to debug problems with code or performance. | ||
| 55 | * IPATH_VERBOSE_TRACING define as 1 if you want additional tracing in | ||
| 56 | * fastpath code | ||
| 57 | * IPATH_TRACE_REGWRITES define as 1 if you want register writes to be | ||
| 58 | * traced in faspath code | ||
| 59 | * _IPATH_TRACING define as 0 if you want to remove all tracing in a | ||
| 60 | * compilation unit | ||
| 61 | * _IPATH_DEBUGGING define as 0 if you want to remove debug prints | ||
| 62 | */ | ||
| 63 | |||
| 64 | /* | ||
| 65 | * The value in the BTH QP field that InfiniPath uses to differentiate | ||
| 66 | * an infinipath protocol IB packet vs standard IB transport | ||
| 67 | */ | ||
| 68 | #define IPATH_KD_QP 0x656b79 | ||
| 69 | |||
| 70 | /* | ||
| 71 | * valid states passed to ipath_set_linkstate() user call | ||
| 72 | */ | ||
| 73 | #define IPATH_IB_LINKDOWN 0 | ||
| 74 | #define IPATH_IB_LINKARM 1 | ||
| 75 | #define IPATH_IB_LINKACTIVE 2 | ||
| 76 | #define IPATH_IB_LINKINIT 3 | ||
| 77 | #define IPATH_IB_LINKDOWN_SLEEP 4 | ||
| 78 | #define IPATH_IB_LINKDOWN_DISABLE 5 | ||
| 79 | |||
| 80 | /* | ||
| 81 | * stats maintained by the driver. For now, at least, this is global | ||
| 82 | * to all minor devices. | ||
| 83 | */ | ||
| 84 | struct infinipath_stats { | ||
| 85 | /* number of interrupts taken */ | ||
| 86 | __u64 sps_ints; | ||
| 87 | /* number of interrupts for errors */ | ||
| 88 | __u64 sps_errints; | ||
| 89 | /* number of errors from chip (not incl. packet errors or CRC) */ | ||
| 90 | __u64 sps_errs; | ||
| 91 | /* number of packet errors from chip other than CRC */ | ||
| 92 | __u64 sps_pkterrs; | ||
| 93 | /* number of packets with CRC errors (ICRC and VCRC) */ | ||
| 94 | __u64 sps_crcerrs; | ||
| 95 | /* number of hardware errors reported (parity, etc.) */ | ||
| 96 | __u64 sps_hwerrs; | ||
| 97 | /* number of times IB link changed state unexpectedly */ | ||
| 98 | __u64 sps_iblink; | ||
| 99 | /* no longer used; left for compatibility */ | ||
| 100 | __u64 sps_unused3; | ||
| 101 | /* number of kernel (port0) packets received */ | ||
| 102 | __u64 sps_port0pkts; | ||
| 103 | /* number of "ethernet" packets sent by driver */ | ||
| 104 | __u64 sps_ether_spkts; | ||
| 105 | /* number of "ethernet" packets received by driver */ | ||
| 106 | __u64 sps_ether_rpkts; | ||
| 107 | /* number of SMA packets sent by driver */ | ||
| 108 | __u64 sps_sma_spkts; | ||
| 109 | /* number of SMA packets received by driver */ | ||
| 110 | __u64 sps_sma_rpkts; | ||
| 111 | /* number of times all ports rcvhdrq was full and packet dropped */ | ||
| 112 | __u64 sps_hdrqfull; | ||
| 113 | /* number of times all ports egrtid was full and packet dropped */ | ||
| 114 | __u64 sps_etidfull; | ||
| 115 | /* | ||
| 116 | * number of times we tried to send from driver, but no pio buffers | ||
| 117 | * avail | ||
| 118 | */ | ||
| 119 | __u64 sps_nopiobufs; | ||
| 120 | /* number of ports currently open */ | ||
| 121 | __u64 sps_ports; | ||
| 122 | /* list of pkeys (other than default) accepted (0 means not set) */ | ||
| 123 | __u16 sps_pkeys[4]; | ||
| 124 | /* lids for up to 4 infinipaths, indexed by infinipath # */ | ||
| 125 | __u16 sps_lid[4]; | ||
| 126 | /* number of user ports per chip (not IB ports) */ | ||
| 127 | __u32 sps_nports; | ||
| 128 | /* not our interrupt, or already handled */ | ||
| 129 | __u32 sps_nullintr; | ||
| 130 | /* max number of packets handled per receive call */ | ||
| 131 | __u32 sps_maxpkts_call; | ||
| 132 | /* avg number of packets handled per receive call */ | ||
| 133 | __u32 sps_avgpkts_call; | ||
| 134 | /* total number of pages locked */ | ||
| 135 | __u64 sps_pagelocks; | ||
| 136 | /* total number of pages unlocked */ | ||
| 137 | __u64 sps_pageunlocks; | ||
| 138 | /* | ||
| 139 | * Number of packets dropped in kernel other than errors (ether | ||
| 140 | * packets if ipath not configured, sma/mad, etc.) | ||
| 141 | */ | ||
| 142 | __u64 sps_krdrops; | ||
| 143 | /* mlids for up to 4 infinipaths, indexed by infinipath # */ | ||
| 144 | __u16 sps_mlid[4]; | ||
| 145 | /* pad for future growth */ | ||
| 146 | __u64 __sps_pad[45]; | ||
| 147 | }; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * These are the status bits readable (in ascii form, 64bit value) | ||
| 151 | * from the "status" sysfs file. | ||
| 152 | */ | ||
| 153 | #define IPATH_STATUS_INITTED 0x1 /* basic initialization done */ | ||
| 154 | #define IPATH_STATUS_DISABLED 0x2 /* hardware disabled */ | ||
| 155 | /* Device has been disabled via admin request */ | ||
| 156 | #define IPATH_STATUS_ADMIN_DISABLED 0x4 | ||
| 157 | #define IPATH_STATUS_OIB_SMA 0x8 /* ipath_mad kernel SMA running */ | ||
| 158 | #define IPATH_STATUS_SMA 0x10 /* user SMA running */ | ||
| 159 | /* Chip has been found and initted */ | ||
| 160 | #define IPATH_STATUS_CHIP_PRESENT 0x20 | ||
| 161 | /* IB link is at ACTIVE, usable for data traffic */ | ||
| 162 | #define IPATH_STATUS_IB_READY 0x40 | ||
| 163 | /* link is configured, LID, MTU, etc. have been set */ | ||
| 164 | #define IPATH_STATUS_IB_CONF 0x80 | ||
| 165 | /* no link established, probably no cable */ | ||
| 166 | #define IPATH_STATUS_IB_NOCABLE 0x100 | ||
| 167 | /* A Fatal hardware error has occurred. */ | ||
| 168 | #define IPATH_STATUS_HWERROR 0x200 | ||
| 169 | |||
| 170 | /* | ||
| 171 | * The list of usermode accessible registers. Also see Reg_* later in file. | ||
| 172 | */ | ||
| 173 | typedef enum _ipath_ureg { | ||
| 174 | /* (RO) DMA RcvHdr to be used next. */ | ||
| 175 | ur_rcvhdrtail = 0, | ||
| 176 | /* (RW) RcvHdr entry to be processed next by host. */ | ||
| 177 | ur_rcvhdrhead = 1, | ||
| 178 | /* (RO) Index of next Eager index to use. */ | ||
| 179 | ur_rcvegrindextail = 2, | ||
| 180 | /* (RW) Eager TID to be processed next */ | ||
| 181 | ur_rcvegrindexhead = 3, | ||
| 182 | /* For internal use only; max register number. */ | ||
| 183 | _IPATH_UregMax | ||
| 184 | } ipath_ureg; | ||
| 185 | |||
| 186 | /* bit values for spi_runtime_flags */ | ||
| 187 | #define IPATH_RUNTIME_HT 0x1 | ||
| 188 | #define IPATH_RUNTIME_PCIE 0x2 | ||
| 189 | #define IPATH_RUNTIME_FORCE_WC_ORDER 0x4 | ||
| 190 | #define IPATH_RUNTIME_RCVHDR_COPY 0x8 | ||
| 191 | |||
| 192 | /* | ||
| 193 | * This structure is returned by ipath_userinit() immediately after | ||
| 194 | * open to get implementation-specific info, and info specific to this | ||
| 195 | * instance. | ||
| 196 | * | ||
| 197 | * This struct must have explict pad fields where type sizes | ||
| 198 | * may result in different alignments between 32 and 64 bit | ||
| 199 | * programs, since the 64 bit * bit kernel requires the user code | ||
| 200 | * to have matching offsets | ||
| 201 | */ | ||
| 202 | struct ipath_base_info { | ||
| 203 | /* version of hardware, for feature checking. */ | ||
| 204 | __u32 spi_hw_version; | ||
| 205 | /* version of software, for feature checking. */ | ||
| 206 | __u32 spi_sw_version; | ||
| 207 | /* InfiniPath port assigned, goes into sent packets */ | ||
| 208 | __u32 spi_port; | ||
| 209 | /* | ||
| 210 | * IB MTU, packets IB data must be less than this. | ||
| 211 | * The MTU is in bytes, and will be a multiple of 4 bytes. | ||
| 212 | */ | ||
| 213 | __u32 spi_mtu; | ||
| 214 | /* | ||
| 215 | * Size of a PIO buffer. Any given packet's total size must be less | ||
| 216 | * than this (in words). Included is the starting control word, so | ||
| 217 | * if 513 is returned, then total pkt size is 512 words or less. | ||
| 218 | */ | ||
| 219 | __u32 spi_piosize; | ||
| 220 | /* size of the TID cache in infinipath, in entries */ | ||
| 221 | __u32 spi_tidcnt; | ||
| 222 | /* size of the TID Eager list in infinipath, in entries */ | ||
| 223 | __u32 spi_tidegrcnt; | ||
| 224 | /* size of a single receive header queue entry. */ | ||
| 225 | __u32 spi_rcvhdrent_size; | ||
| 226 | /* | ||
| 227 | * Count of receive header queue entries allocated. | ||
| 228 | * This may be less than the spu_rcvhdrcnt passed in!. | ||
| 229 | */ | ||
| 230 | __u32 spi_rcvhdr_cnt; | ||
| 231 | |||
| 232 | /* per-chip and other runtime features bitmap (IPATH_RUNTIME_*) */ | ||
| 233 | __u32 spi_runtime_flags; | ||
| 234 | |||
| 235 | /* address where receive buffer queue is mapped into */ | ||
| 236 | __u64 spi_rcvhdr_base; | ||
| 237 | |||
| 238 | /* user program. */ | ||
| 239 | |||
| 240 | /* base address of eager TID receive buffers. */ | ||
| 241 | __u64 spi_rcv_egrbufs; | ||
| 242 | |||
| 243 | /* Allocated by initialization code, not by protocol. */ | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Size of each TID buffer in host memory, starting at | ||
| 247 | * spi_rcv_egrbufs. The buffers are virtually contiguous. | ||
| 248 | */ | ||
| 249 | __u32 spi_rcv_egrbufsize; | ||
| 250 | /* | ||
| 251 | * The special QP (queue pair) value that identifies an infinipath | ||
| 252 | * protocol packet from standard IB packets. More, probably much | ||
| 253 | * more, to be added. | ||
| 254 | */ | ||
| 255 | __u32 spi_qpair; | ||
| 256 | |||
| 257 | /* | ||
| 258 | * User register base for init code, not to be used directly by | ||
| 259 | * protocol or applications. | ||
| 260 | */ | ||
| 261 | __u64 __spi_uregbase; | ||
| 262 | /* | ||
| 263 | * Maximum buffer size in bytes that can be used in a single TID | ||
| 264 | * entry (assuming the buffer is aligned to this boundary). This is | ||
| 265 | * the minimum of what the hardware and software support Guaranteed | ||
| 266 | * to be a power of 2. | ||
| 267 | */ | ||
| 268 | __u32 spi_tid_maxsize; | ||
| 269 | /* | ||
| 270 | * alignment of each pio send buffer (byte count | ||
| 271 | * to add to spi_piobufbase to get to second buffer) | ||
| 272 | */ | ||
| 273 | __u32 spi_pioalign; | ||
| 274 | /* | ||
| 275 | * The index of the first pio buffer available to this process; | ||
| 276 | * needed to do lookup in spi_pioavailaddr; not added to | ||
| 277 | * spi_piobufbase. | ||
| 278 | */ | ||
| 279 | __u32 spi_pioindex; | ||
| 280 | /* number of buffers mapped for this process */ | ||
| 281 | __u32 spi_piocnt; | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Base address of writeonly pio buffers for this process. | ||
| 285 | * Each buffer has spi_piosize words, and is aligned on spi_pioalign | ||
| 286 | * boundaries. spi_piocnt buffers are mapped from this address | ||
| 287 | */ | ||
| 288 | __u64 spi_piobufbase; | ||
| 289 | |||
| 290 | /* | ||
| 291 | * Base address of readonly memory copy of the pioavail registers. | ||
| 292 | * There are 2 bits for each buffer. | ||
| 293 | */ | ||
| 294 | __u64 spi_pioavailaddr; | ||
| 295 | |||
| 296 | /* | ||
| 297 | * Address where driver updates a copy of the interface and driver | ||
| 298 | * status (IPATH_STATUS_*) as a 64 bit value. It's followed by a | ||
| 299 | * string indicating hardware error, if there was one. | ||
| 300 | */ | ||
| 301 | __u64 spi_status; | ||
| 302 | |||
| 303 | /* number of chip ports available to user processes */ | ||
| 304 | __u32 spi_nports; | ||
| 305 | /* unit number of chip we are using */ | ||
| 306 | __u32 spi_unit; | ||
| 307 | /* num bufs in each contiguous set */ | ||
| 308 | __u32 spi_rcv_egrperchunk; | ||
| 309 | /* size in bytes of each contiguous set */ | ||
| 310 | __u32 spi_rcv_egrchunksize; | ||
| 311 | /* total size of mmap to cover full rcvegrbuffers */ | ||
| 312 | __u32 spi_rcv_egrbuftotlen; | ||
| 313 | } __attribute__ ((aligned(8))); | ||
| 314 | |||
| 315 | |||
| 316 | /* | ||
| 317 | * This version number is given to the driver by the user code during | ||
| 318 | * initialization in the spu_userversion field of ipath_user_info, so | ||
| 319 | * the driver can check for compatibility with user code. | ||
| 320 | * | ||
| 321 | * The major version changes when data structures | ||
| 322 | * change in an incompatible way. The driver must be the same or higher | ||
| 323 | * for initialization to succeed. In some cases, a higher version | ||
| 324 | * driver will not interoperate with older software, and initialization | ||
| 325 | * will return an error. | ||
| 326 | */ | ||
| 327 | #define IPATH_USER_SWMAJOR 1 | ||
| 328 | |||
| 329 | /* | ||
| 330 | * Minor version differences are always compatible | ||
| 331 | * a within a major version, however if if user software is larger | ||
| 332 | * than driver software, some new features and/or structure fields | ||
| 333 | * may not be implemented; the user code must deal with this if it | ||
| 334 | * cares, or it must abort after initialization reports the difference | ||
| 335 | */ | ||
| 336 | #define IPATH_USER_SWMINOR 2 | ||
| 337 | |||
| 338 | #define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR) | ||
| 339 | |||
| 340 | #define IPATH_KERN_TYPE 0 | ||
| 341 | |||
| 342 | /* | ||
| 343 | * Similarly, this is the kernel version going back to the user. It's | ||
| 344 | * slightly different, in that we want to tell if the driver was built as | ||
| 345 | * part of a PathScale release, or from the driver from OpenIB, kernel.org, | ||
| 346 | * or a standard distribution, for support reasons. The high bit is 0 for | ||
| 347 | * non-PathScale, and 1 for PathScale-built/supplied. | ||
| 348 | * | ||
| 349 | * It's returned by the driver to the user code during initialization in the | ||
| 350 | * spi_sw_version field of ipath_base_info, so the user code can in turn | ||
| 351 | * check for compatibility with the kernel. | ||
| 352 | */ | ||
| 353 | #define IPATH_KERN_SWVERSION ((IPATH_KERN_TYPE<<31) | IPATH_USER_SWVERSION) | ||
| 354 | |||
| 355 | /* | ||
| 356 | * This structure is passed to ipath_userinit() to tell the driver where | ||
| 357 | * user code buffers are, sizes, etc. The offsets and sizes of the | ||
| 358 | * fields must remain unchanged, for binary compatibility. It can | ||
| 359 | * be extended, if userversion is changed so user code can tell, if needed | ||
| 360 | */ | ||
| 361 | struct ipath_user_info { | ||
| 362 | /* | ||
| 363 | * version of user software, to detect compatibility issues. | ||
| 364 | * Should be set to IPATH_USER_SWVERSION. | ||
| 365 | */ | ||
| 366 | __u32 spu_userversion; | ||
| 367 | |||
| 368 | /* desired number of receive header queue entries */ | ||
| 369 | __u32 spu_rcvhdrcnt; | ||
| 370 | |||
| 371 | /* size of struct base_info to write to */ | ||
| 372 | __u32 spu_base_info_size; | ||
| 373 | |||
| 374 | /* | ||
| 375 | * number of words in KD protocol header | ||
| 376 | * This tells InfiniPath how many words to copy to rcvhdrq. If 0, | ||
| 377 | * kernel uses a default. Once set, attempts to set any other value | ||
| 378 | * are an error (EAGAIN) until driver is reloaded. | ||
| 379 | */ | ||
| 380 | __u32 spu_rcvhdrsize; | ||
| 381 | |||
| 382 | /* | ||
| 383 | * cache line aligned (64 byte) user address to | ||
| 384 | * which the rcvhdrtail register will be written by infinipath | ||
| 385 | * whenever it changes, so that no chip registers are read in | ||
| 386 | * the performance path. | ||
| 387 | */ | ||
| 388 | __u64 spu_rcvhdraddr; | ||
| 389 | |||
| 390 | /* | ||
| 391 | * address of struct base_info to write to | ||
| 392 | */ | ||
| 393 | __u64 spu_base_info; | ||
| 394 | |||
| 395 | } __attribute__ ((aligned(8))); | ||
| 396 | |||
| 397 | /* User commands. */ | ||
| 398 | |||
| 399 | #define IPATH_CMD_MIN 16 | ||
| 400 | |||
| 401 | #define IPATH_CMD_USER_INIT 16 /* set up userspace */ | ||
| 402 | #define IPATH_CMD_PORT_INFO 17 /* find out what resources we got */ | ||
| 403 | #define IPATH_CMD_RECV_CTRL 18 /* control receipt of packets */ | ||
| 404 | #define IPATH_CMD_TID_UPDATE 19 /* update expected TID entries */ | ||
| 405 | #define IPATH_CMD_TID_FREE 20 /* free expected TID entries */ | ||
| 406 | #define IPATH_CMD_SET_PART_KEY 21 /* add partition key */ | ||
| 407 | |||
| 408 | #define IPATH_CMD_MAX 21 | ||
| 409 | |||
| 410 | struct ipath_port_info { | ||
| 411 | __u32 num_active; /* number of active units */ | ||
| 412 | __u32 unit; /* unit (chip) assigned to caller */ | ||
| 413 | __u32 port; /* port on unit assigned to caller */ | ||
| 414 | }; | ||
| 415 | |||
| 416 | struct ipath_tid_info { | ||
| 417 | __u32 tidcnt; | ||
| 418 | /* make structure same size in 32 and 64 bit */ | ||
| 419 | __u32 tid__unused; | ||
| 420 | /* virtual address of first page in transfer */ | ||
| 421 | __u64 tidvaddr; | ||
| 422 | /* pointer (same size 32/64 bit) to __u16 tid array */ | ||
| 423 | __u64 tidlist; | ||
| 424 | |||
| 425 | /* | ||
| 426 | * pointer (same size 32/64 bit) to bitmap of TIDs used | ||
| 427 | * for this call; checked for being large enough at open | ||
| 428 | */ | ||
| 429 | __u64 tidmap; | ||
| 430 | }; | ||
| 431 | |||
| 432 | struct ipath_cmd { | ||
| 433 | __u32 type; /* command type */ | ||
| 434 | union { | ||
| 435 | struct ipath_tid_info tid_info; | ||
| 436 | struct ipath_user_info user_info; | ||
| 437 | /* address in userspace of struct ipath_port_info to | ||
| 438 | write result to */ | ||
| 439 | __u64 port_info; | ||
| 440 | /* enable/disable receipt of packets */ | ||
| 441 | __u32 recv_ctrl; | ||
| 442 | /* partition key to set */ | ||
| 443 | __u16 part_key; | ||
| 444 | } cmd; | ||
| 445 | }; | ||
| 446 | |||
| 447 | struct ipath_iovec { | ||
| 448 | /* Pointer to data, but same size 32 and 64 bit */ | ||
| 449 | __u64 iov_base; | ||
| 450 | |||
| 451 | /* | ||
| 452 | * Length of data; don't need 64 bits, but want | ||
| 453 | * ipath_sendpkt to remain same size as before 32 bit changes, so... | ||
| 454 | */ | ||
| 455 | __u64 iov_len; | ||
| 456 | }; | ||
| 457 | |||
| 458 | /* | ||
| 459 | * Describes a single packet for send. Each packet can have one or more | ||
| 460 | * buffers, but the total length (exclusive of IB headers) must be less | ||
| 461 | * than the MTU, and if using the PIO method, entire packet length, | ||
| 462 | * including IB headers, must be less than the ipath_piosize value (words). | ||
| 463 | * Use of this necessitates including sys/uio.h | ||
| 464 | */ | ||
| 465 | struct __ipath_sendpkt { | ||
| 466 | __u32 sps_flags; /* flags for packet (TBD) */ | ||
| 467 | __u32 sps_cnt; /* number of entries to use in sps_iov */ | ||
| 468 | /* array of iov's describing packet. TEMPORARY */ | ||
| 469 | struct ipath_iovec sps_iov[4]; | ||
| 470 | }; | ||
| 471 | |||
| 472 | /* Passed into SMA special file's ->read and ->write methods. */ | ||
| 473 | struct ipath_sma_pkt | ||
| 474 | { | ||
| 475 | __u32 unit; /* unit on which to send packet */ | ||
| 476 | __u64 data; /* address of payload in userspace */ | ||
| 477 | __u32 len; /* length of payload */ | ||
| 478 | }; | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Data layout in I2C flash (for GUID, etc.) | ||
| 482 | * All fields are little-endian binary unless otherwise stated | ||
| 483 | */ | ||
| 484 | #define IPATH_FLASH_VERSION 1 | ||
| 485 | struct ipath_flash { | ||
| 486 | /* flash layout version (IPATH_FLASH_VERSION) */ | ||
| 487 | __u8 if_fversion; | ||
| 488 | /* checksum protecting if_length bytes */ | ||
| 489 | __u8 if_csum; | ||
| 490 | /* | ||
| 491 | * valid length (in use, protected by if_csum), including | ||
| 492 | * if_fversion and if_sum themselves) | ||
| 493 | */ | ||
| 494 | __u8 if_length; | ||
| 495 | /* the GUID, in network order */ | ||
| 496 | __u8 if_guid[8]; | ||
| 497 | /* number of GUIDs to use, starting from if_guid */ | ||
| 498 | __u8 if_numguid; | ||
| 499 | /* the board serial number, in ASCII */ | ||
| 500 | char if_serial[12]; | ||
| 501 | /* board mfg date (YYYYMMDD ASCII) */ | ||
| 502 | char if_mfgdate[8]; | ||
| 503 | /* last board rework/test date (YYYYMMDD ASCII) */ | ||
| 504 | char if_testdate[8]; | ||
| 505 | /* logging of error counts, TBD */ | ||
| 506 | __u8 if_errcntp[4]; | ||
| 507 | /* powered on hours, updated at driver unload */ | ||
| 508 | __u8 if_powerhour[2]; | ||
| 509 | /* ASCII free-form comment field */ | ||
| 510 | char if_comment[32]; | ||
| 511 | /* 78 bytes used, min flash size is 128 bytes */ | ||
| 512 | __u8 if_future[50]; | ||
| 513 | }; | ||
| 514 | |||
| 515 | /* | ||
| 516 | * These are the counters implemented in the chip, and are listed in order. | ||
| 517 | * The InterCaps naming is taken straight from the chip spec. | ||
| 518 | */ | ||
| 519 | struct infinipath_counters { | ||
| 520 | __u64 LBIntCnt; | ||
| 521 | __u64 LBFlowStallCnt; | ||
| 522 | __u64 Reserved1; | ||
| 523 | __u64 TxUnsupVLErrCnt; | ||
| 524 | __u64 TxDataPktCnt; | ||
| 525 | __u64 TxFlowPktCnt; | ||
| 526 | __u64 TxDwordCnt; | ||
| 527 | __u64 TxLenErrCnt; | ||
| 528 | __u64 TxMaxMinLenErrCnt; | ||
| 529 | __u64 TxUnderrunCnt; | ||
| 530 | __u64 TxFlowStallCnt; | ||
| 531 | __u64 TxDroppedPktCnt; | ||
| 532 | __u64 RxDroppedPktCnt; | ||
| 533 | __u64 RxDataPktCnt; | ||
| 534 | __u64 RxFlowPktCnt; | ||
| 535 | __u64 RxDwordCnt; | ||
| 536 | __u64 RxLenErrCnt; | ||
| 537 | __u64 RxMaxMinLenErrCnt; | ||
| 538 | __u64 RxICRCErrCnt; | ||
| 539 | __u64 RxVCRCErrCnt; | ||
| 540 | __u64 RxFlowCtrlErrCnt; | ||
| 541 | __u64 RxBadFormatCnt; | ||
| 542 | __u64 RxLinkProblemCnt; | ||
| 543 | __u64 RxEBPCnt; | ||
| 544 | __u64 RxLPCRCErrCnt; | ||
| 545 | __u64 RxBufOvflCnt; | ||
| 546 | __u64 RxTIDFullErrCnt; | ||
| 547 | __u64 RxTIDValidErrCnt; | ||
| 548 | __u64 RxPKeyMismatchCnt; | ||
| 549 | __u64 RxP0HdrEgrOvflCnt; | ||
| 550 | __u64 RxP1HdrEgrOvflCnt; | ||
| 551 | __u64 RxP2HdrEgrOvflCnt; | ||
| 552 | __u64 RxP3HdrEgrOvflCnt; | ||
| 553 | __u64 RxP4HdrEgrOvflCnt; | ||
| 554 | __u64 RxP5HdrEgrOvflCnt; | ||
| 555 | __u64 RxP6HdrEgrOvflCnt; | ||
| 556 | __u64 RxP7HdrEgrOvflCnt; | ||
| 557 | __u64 RxP8HdrEgrOvflCnt; | ||
| 558 | __u64 Reserved6; | ||
| 559 | __u64 Reserved7; | ||
| 560 | __u64 IBStatusChangeCnt; | ||
| 561 | __u64 IBLinkErrRecoveryCnt; | ||
| 562 | __u64 IBLinkDownedCnt; | ||
| 563 | __u64 IBSymbolErrCnt; | ||
| 564 | }; | ||
| 565 | |||
| 566 | /* | ||
| 567 | * The next set of defines are for packet headers, and chip register | ||
| 568 | * and memory bits that are visible to and/or used by user-mode software | ||
| 569 | * The other bits that are used only by the driver or diags are in | ||
| 570 | * ipath_registers.h | ||
| 571 | */ | ||
| 572 | |||
| 573 | /* RcvHdrFlags bits */ | ||
| 574 | #define INFINIPATH_RHF_LENGTH_MASK 0x7FF | ||
| 575 | #define INFINIPATH_RHF_LENGTH_SHIFT 0 | ||
| 576 | #define INFINIPATH_RHF_RCVTYPE_MASK 0x7 | ||
| 577 | #define INFINIPATH_RHF_RCVTYPE_SHIFT 11 | ||
| 578 | #define INFINIPATH_RHF_EGRINDEX_MASK 0x7FF | ||
| 579 | #define INFINIPATH_RHF_EGRINDEX_SHIFT 16 | ||
| 580 | #define INFINIPATH_RHF_H_ICRCERR 0x80000000 | ||
| 581 | #define INFINIPATH_RHF_H_VCRCERR 0x40000000 | ||
| 582 | #define INFINIPATH_RHF_H_PARITYERR 0x20000000 | ||
| 583 | #define INFINIPATH_RHF_H_LENERR 0x10000000 | ||
| 584 | #define INFINIPATH_RHF_H_MTUERR 0x08000000 | ||
| 585 | #define INFINIPATH_RHF_H_IHDRERR 0x04000000 | ||
| 586 | #define INFINIPATH_RHF_H_TIDERR 0x02000000 | ||
| 587 | #define INFINIPATH_RHF_H_MKERR 0x01000000 | ||
| 588 | #define INFINIPATH_RHF_H_IBERR 0x00800000 | ||
| 589 | #define INFINIPATH_RHF_L_SWA 0x00008000 | ||
| 590 | #define INFINIPATH_RHF_L_SWB 0x00004000 | ||
| 591 | |||
| 592 | /* infinipath header fields */ | ||
| 593 | #define INFINIPATH_I_VERS_MASK 0xF | ||
| 594 | #define INFINIPATH_I_VERS_SHIFT 28 | ||
| 595 | #define INFINIPATH_I_PORT_MASK 0xF | ||
| 596 | #define INFINIPATH_I_PORT_SHIFT 24 | ||
| 597 | #define INFINIPATH_I_TID_MASK 0x7FF | ||
| 598 | #define INFINIPATH_I_TID_SHIFT 13 | ||
| 599 | #define INFINIPATH_I_OFFSET_MASK 0x1FFF | ||
| 600 | #define INFINIPATH_I_OFFSET_SHIFT 0 | ||
| 601 | |||
| 602 | /* K_PktFlags bits */ | ||
| 603 | #define INFINIPATH_KPF_INTR 0x1 | ||
| 604 | |||
| 605 | /* SendPIO per-buffer control */ | ||
| 606 | #define INFINIPATH_SP_LENGTHP1_MASK 0x3FF | ||
| 607 | #define INFINIPATH_SP_LENGTHP1_SHIFT 0 | ||
| 608 | #define INFINIPATH_SP_INTR 0x80000000 | ||
| 609 | #define INFINIPATH_SP_TEST 0x40000000 | ||
| 610 | #define INFINIPATH_SP_TESTEBP 0x20000000 | ||
| 611 | |||
| 612 | /* SendPIOAvail bits */ | ||
| 613 | #define INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT 1 | ||
| 614 | #define INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT 0 | ||
| 615 | |||
| 616 | #endif /* _IPATH_COMMON_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c new file mode 100644 index 000000000000..7ece1135ddfe --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_cq.c | |||
| @@ -0,0 +1,295 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/err.h> | ||
| 34 | #include <linux/vmalloc.h> | ||
| 35 | |||
| 36 | #include "ipath_verbs.h" | ||
| 37 | |||
| 38 | /** | ||
| 39 | * ipath_cq_enter - add a new entry to the completion queue | ||
| 40 | * @cq: completion queue | ||
| 41 | * @entry: work completion entry to add | ||
| 42 | * @sig: true if @entry is a solicitated entry | ||
| 43 | * | ||
| 44 | * This may be called with one of the qp->s_lock or qp->r_rq.lock held. | ||
| 45 | */ | ||
| 46 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited) | ||
| 47 | { | ||
| 48 | unsigned long flags; | ||
| 49 | u32 next; | ||
| 50 | |||
| 51 | spin_lock_irqsave(&cq->lock, flags); | ||
| 52 | |||
| 53 | if (cq->head == cq->ibcq.cqe) | ||
| 54 | next = 0; | ||
| 55 | else | ||
| 56 | next = cq->head + 1; | ||
| 57 | if (unlikely(next == cq->tail)) { | ||
| 58 | spin_unlock_irqrestore(&cq->lock, flags); | ||
| 59 | if (cq->ibcq.event_handler) { | ||
| 60 | struct ib_event ev; | ||
| 61 | |||
| 62 | ev.device = cq->ibcq.device; | ||
| 63 | ev.element.cq = &cq->ibcq; | ||
| 64 | ev.event = IB_EVENT_CQ_ERR; | ||
| 65 | cq->ibcq.event_handler(&ev, cq->ibcq.cq_context); | ||
| 66 | } | ||
| 67 | return; | ||
| 68 | } | ||
| 69 | cq->queue[cq->head] = *entry; | ||
| 70 | cq->head = next; | ||
| 71 | |||
| 72 | if (cq->notify == IB_CQ_NEXT_COMP || | ||
| 73 | (cq->notify == IB_CQ_SOLICITED && solicited)) { | ||
| 74 | cq->notify = IB_CQ_NONE; | ||
| 75 | cq->triggered++; | ||
| 76 | /* | ||
| 77 | * This will cause send_complete() to be called in | ||
| 78 | * another thread. | ||
| 79 | */ | ||
| 80 | tasklet_hi_schedule(&cq->comptask); | ||
| 81 | } | ||
| 82 | |||
| 83 | spin_unlock_irqrestore(&cq->lock, flags); | ||
| 84 | |||
| 85 | if (entry->status != IB_WC_SUCCESS) | ||
| 86 | to_idev(cq->ibcq.device)->n_wqe_errs++; | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * ipath_poll_cq - poll for work completion entries | ||
| 91 | * @ibcq: the completion queue to poll | ||
| 92 | * @num_entries: the maximum number of entries to return | ||
| 93 | * @entry: pointer to array where work completions are placed | ||
| 94 | * | ||
| 95 | * Returns the number of completion entries polled. | ||
| 96 | * | ||
| 97 | * This may be called from interrupt context. Also called by ib_poll_cq() | ||
| 98 | * in the generic verbs code. | ||
| 99 | */ | ||
| 100 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | ||
| 101 | { | ||
| 102 | struct ipath_cq *cq = to_icq(ibcq); | ||
| 103 | unsigned long flags; | ||
| 104 | int npolled; | ||
| 105 | |||
| 106 | spin_lock_irqsave(&cq->lock, flags); | ||
| 107 | |||
| 108 | for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { | ||
| 109 | if (cq->tail == cq->head) | ||
| 110 | break; | ||
| 111 | *entry = cq->queue[cq->tail]; | ||
| 112 | if (cq->tail == cq->ibcq.cqe) | ||
| 113 | cq->tail = 0; | ||
| 114 | else | ||
| 115 | cq->tail++; | ||
| 116 | } | ||
| 117 | |||
| 118 | spin_unlock_irqrestore(&cq->lock, flags); | ||
| 119 | |||
| 120 | return npolled; | ||
| 121 | } | ||
| 122 | |||
| 123 | static void send_complete(unsigned long data) | ||
| 124 | { | ||
| 125 | struct ipath_cq *cq = (struct ipath_cq *)data; | ||
| 126 | |||
| 127 | /* | ||
| 128 | * The completion handler will most likely rearm the notification | ||
| 129 | * and poll for all pending entries. If a new completion entry | ||
| 130 | * is added while we are in this routine, tasklet_hi_schedule() | ||
| 131 | * won't call us again until we return so we check triggered to | ||
| 132 | * see if we need to call the handler again. | ||
| 133 | */ | ||
| 134 | for (;;) { | ||
| 135 | u8 triggered = cq->triggered; | ||
| 136 | |||
| 137 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); | ||
| 138 | |||
| 139 | if (cq->triggered == triggered) | ||
| 140 | return; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * ipath_create_cq - create a completion queue | ||
| 146 | * @ibdev: the device this completion queue is attached to | ||
| 147 | * @entries: the minimum size of the completion queue | ||
| 148 | * @context: unused by the InfiniPath driver | ||
| 149 | * @udata: unused by the InfiniPath driver | ||
| 150 | * | ||
| 151 | * Returns a pointer to the completion queue or negative errno values | ||
| 152 | * for failure. | ||
| 153 | * | ||
| 154 | * Called by ib_create_cq() in the generic verbs code. | ||
| 155 | */ | ||
| 156 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, | ||
| 157 | struct ib_ucontext *context, | ||
| 158 | struct ib_udata *udata) | ||
| 159 | { | ||
| 160 | struct ipath_cq *cq; | ||
| 161 | struct ib_wc *wc; | ||
| 162 | struct ib_cq *ret; | ||
| 163 | |||
| 164 | /* | ||
| 165 | * Need to use vmalloc() if we want to support large #s of | ||
| 166 | * entries. | ||
| 167 | */ | ||
| 168 | cq = kmalloc(sizeof(*cq), GFP_KERNEL); | ||
| 169 | if (!cq) { | ||
| 170 | ret = ERR_PTR(-ENOMEM); | ||
| 171 | goto bail; | ||
| 172 | } | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Need to use vmalloc() if we want to support large #s of entries. | ||
| 176 | */ | ||
| 177 | wc = vmalloc(sizeof(*wc) * (entries + 1)); | ||
| 178 | if (!wc) { | ||
| 179 | kfree(cq); | ||
| 180 | ret = ERR_PTR(-ENOMEM); | ||
| 181 | goto bail; | ||
| 182 | } | ||
| 183 | /* | ||
| 184 | * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe. | ||
| 185 | * The number of entries should be >= the number requested or return | ||
| 186 | * an error. | ||
| 187 | */ | ||
| 188 | cq->ibcq.cqe = entries; | ||
| 189 | cq->notify = IB_CQ_NONE; | ||
| 190 | cq->triggered = 0; | ||
| 191 | spin_lock_init(&cq->lock); | ||
| 192 | tasklet_init(&cq->comptask, send_complete, (unsigned long)cq); | ||
| 193 | cq->head = 0; | ||
| 194 | cq->tail = 0; | ||
| 195 | cq->queue = wc; | ||
| 196 | |||
| 197 | ret = &cq->ibcq; | ||
| 198 | |||
| 199 | bail: | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | |||
| 203 | /** | ||
| 204 | * ipath_destroy_cq - destroy a completion queue | ||
| 205 | * @ibcq: the completion queue to destroy. | ||
| 206 | * | ||
| 207 | * Returns 0 for success. | ||
| 208 | * | ||
| 209 | * Called by ib_destroy_cq() in the generic verbs code. | ||
| 210 | */ | ||
| 211 | int ipath_destroy_cq(struct ib_cq *ibcq) | ||
| 212 | { | ||
| 213 | struct ipath_cq *cq = to_icq(ibcq); | ||
| 214 | |||
| 215 | tasklet_kill(&cq->comptask); | ||
| 216 | vfree(cq->queue); | ||
| 217 | kfree(cq); | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | /** | ||
| 223 | * ipath_req_notify_cq - change the notification type for a completion queue | ||
| 224 | * @ibcq: the completion queue | ||
| 225 | * @notify: the type of notification to request | ||
| 226 | * | ||
| 227 | * Returns 0 for success. | ||
| 228 | * | ||
| 229 | * This may be called from interrupt context. Also called by | ||
| 230 | * ib_req_notify_cq() in the generic verbs code. | ||
| 231 | */ | ||
| 232 | int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) | ||
| 233 | { | ||
| 234 | struct ipath_cq *cq = to_icq(ibcq); | ||
| 235 | unsigned long flags; | ||
| 236 | |||
| 237 | spin_lock_irqsave(&cq->lock, flags); | ||
| 238 | /* | ||
| 239 | * Don't change IB_CQ_NEXT_COMP to IB_CQ_SOLICITED but allow | ||
| 240 | * any other transitions. | ||
| 241 | */ | ||
| 242 | if (cq->notify != IB_CQ_NEXT_COMP) | ||
| 243 | cq->notify = notify; | ||
| 244 | spin_unlock_irqrestore(&cq->lock, flags); | ||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | ||
| 249 | { | ||
| 250 | struct ipath_cq *cq = to_icq(ibcq); | ||
| 251 | struct ib_wc *wc, *old_wc; | ||
| 252 | u32 n; | ||
| 253 | int ret; | ||
| 254 | |||
| 255 | /* | ||
| 256 | * Need to use vmalloc() if we want to support large #s of entries. | ||
| 257 | */ | ||
| 258 | wc = vmalloc(sizeof(*wc) * (cqe + 1)); | ||
| 259 | if (!wc) { | ||
| 260 | ret = -ENOMEM; | ||
| 261 | goto bail; | ||
| 262 | } | ||
| 263 | |||
| 264 | spin_lock_irq(&cq->lock); | ||
| 265 | if (cq->head < cq->tail) | ||
| 266 | n = cq->ibcq.cqe + 1 + cq->head - cq->tail; | ||
| 267 | else | ||
| 268 | n = cq->head - cq->tail; | ||
| 269 | if (unlikely((u32)cqe < n)) { | ||
| 270 | spin_unlock_irq(&cq->lock); | ||
| 271 | vfree(wc); | ||
| 272 | ret = -EOVERFLOW; | ||
| 273 | goto bail; | ||
| 274 | } | ||
| 275 | for (n = 0; cq->tail != cq->head; n++) { | ||
| 276 | wc[n] = cq->queue[cq->tail]; | ||
| 277 | if (cq->tail == cq->ibcq.cqe) | ||
| 278 | cq->tail = 0; | ||
| 279 | else | ||
| 280 | cq->tail++; | ||
| 281 | } | ||
| 282 | cq->ibcq.cqe = cqe; | ||
| 283 | cq->head = n; | ||
| 284 | cq->tail = 0; | ||
| 285 | old_wc = cq->queue; | ||
| 286 | cq->queue = wc; | ||
| 287 | spin_unlock_irq(&cq->lock); | ||
| 288 | |||
| 289 | vfree(old_wc); | ||
| 290 | |||
| 291 | ret = 0; | ||
| 292 | |||
| 293 | bail: | ||
| 294 | return ret; | ||
| 295 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_debug.h b/drivers/infiniband/hw/ipath/ipath_debug.h new file mode 100644 index 000000000000..593e28969c69 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_debug.h | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _IPATH_DEBUG_H | ||
| 34 | #define _IPATH_DEBUG_H | ||
| 35 | |||
| 36 | #ifndef _IPATH_DEBUGGING /* debugging enabled or not */ | ||
| 37 | #define _IPATH_DEBUGGING 1 | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #if _IPATH_DEBUGGING | ||
| 41 | |||
| 42 | /* | ||
| 43 | * Mask values for debugging. The scheme allows us to compile out any | ||
| 44 | * of the debug tracing stuff, and if compiled in, to enable or disable | ||
| 45 | * dynamically. This can be set at modprobe time also: | ||
| 46 | * modprobe infinipath.ko infinipath_debug=7 | ||
| 47 | */ | ||
| 48 | |||
| 49 | #define __IPATH_INFO 0x1 /* generic low verbosity stuff */ | ||
| 50 | #define __IPATH_DBG 0x2 /* generic debug */ | ||
| 51 | #define __IPATH_TRSAMPLE 0x8 /* generate trace buffer sample entries */ | ||
| 52 | /* leave some low verbosity spots open */ | ||
| 53 | #define __IPATH_VERBDBG 0x40 /* very verbose debug */ | ||
| 54 | #define __IPATH_PKTDBG 0x80 /* print packet data */ | ||
| 55 | /* print process startup (init)/exit messages */ | ||
| 56 | #define __IPATH_PROCDBG 0x100 | ||
| 57 | /* print mmap/nopage stuff, not using VDBG any more */ | ||
| 58 | #define __IPATH_MMDBG 0x200 | ||
| 59 | #define __IPATH_USER_SEND 0x1000 /* use user mode send */ | ||
| 60 | #define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */ | ||
| 61 | #define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */ | ||
| 62 | #define __IPATH_SMADBG 0x8000 /* sma packet debug */ | ||
| 63 | #define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) general debug on */ | ||
| 64 | #define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings on */ | ||
| 65 | #define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors on */ | ||
| 66 | #define __IPATH_IPATHPD 0x80000 /* Ethernet (IPATH) packet dump on */ | ||
| 67 | #define __IPATH_IPATHTABLE 0x100000 /* Ethernet (IPATH) table dump on */ | ||
| 68 | |||
| 69 | #else /* _IPATH_DEBUGGING */ | ||
| 70 | |||
| 71 | /* | ||
| 72 | * define all of these even with debugging off, for the few places that do | ||
| 73 | * if(infinipath_debug & _IPATH_xyzzy), but in a way that will make the | ||
| 74 | * compiler eliminate the code | ||
| 75 | */ | ||
| 76 | |||
| 77 | #define __IPATH_INFO 0x0 /* generic low verbosity stuff */ | ||
| 78 | #define __IPATH_DBG 0x0 /* generic debug */ | ||
| 79 | #define __IPATH_TRSAMPLE 0x0 /* generate trace buffer sample entries */ | ||
| 80 | #define __IPATH_VERBDBG 0x0 /* very verbose debug */ | ||
| 81 | #define __IPATH_PKTDBG 0x0 /* print packet data */ | ||
| 82 | #define __IPATH_PROCDBG 0x0 /* print process startup (init)/exit messages */ | ||
| 83 | /* print mmap/nopage stuff, not using VDBG any more */ | ||
| 84 | #define __IPATH_MMDBG 0x0 | ||
| 85 | #define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ | ||
| 86 | #define __IPATH_SMADBG 0x0 /* print process startup (init)/exit messages */#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ | ||
| 87 | #define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */ | ||
| 88 | #define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */ | ||
| 89 | #define __IPATH_IPATHPD 0x0 /* Ethernet (IPATH) packet dump on */ | ||
| 90 | #define __IPATH_IPATHTABLE 0x0 /* Ethernet (IPATH) packet dump on */ | ||
| 91 | |||
| 92 | #endif /* _IPATH_DEBUGGING */ | ||
| 93 | |||
| 94 | #define __IPATH_VERBOSEDBG __IPATH_VERBDBG | ||
| 95 | |||
| 96 | #endif /* _IPATH_DEBUG_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c new file mode 100644 index 000000000000..cd533cf951c2 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
| @@ -0,0 +1,379 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* | ||
| 34 | * This file contains support for diagnostic functions. It is accessed by | ||
| 35 | * opening the ipath_diag device, normally minor number 129. Diagnostic use | ||
| 36 | * of the InfiniPath chip may render the chip or board unusable until the | ||
| 37 | * driver is unloaded, or in some cases, until the system is rebooted. | ||
| 38 | * | ||
| 39 | * Accesses to the chip through this interface are not similar to going | ||
| 40 | * through the /sys/bus/pci resource mmap interface. | ||
| 41 | */ | ||
| 42 | |||
| 43 | #include <linux/pci.h> | ||
| 44 | #include <asm/uaccess.h> | ||
| 45 | |||
| 46 | #include "ipath_common.h" | ||
| 47 | #include "ipath_kernel.h" | ||
| 48 | #include "ips_common.h" | ||
| 49 | #include "ipath_layer.h" | ||
| 50 | |||
| 51 | int ipath_diag_inuse; | ||
| 52 | static int diag_set_link; | ||
| 53 | |||
| 54 | static int ipath_diag_open(struct inode *in, struct file *fp); | ||
| 55 | static int ipath_diag_release(struct inode *in, struct file *fp); | ||
| 56 | static ssize_t ipath_diag_read(struct file *fp, char __user *data, | ||
| 57 | size_t count, loff_t *off); | ||
| 58 | static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | ||
| 59 | size_t count, loff_t *off); | ||
| 60 | |||
| 61 | static struct file_operations diag_file_ops = { | ||
| 62 | .owner = THIS_MODULE, | ||
| 63 | .write = ipath_diag_write, | ||
| 64 | .read = ipath_diag_read, | ||
| 65 | .open = ipath_diag_open, | ||
| 66 | .release = ipath_diag_release | ||
| 67 | }; | ||
| 68 | |||
| 69 | static struct cdev *diag_cdev; | ||
| 70 | static struct class_device *diag_class_dev; | ||
| 71 | |||
| 72 | int ipath_diag_init(void) | ||
| 73 | { | ||
| 74 | return ipath_cdev_init(IPATH_DIAG_MINOR, "ipath_diag", | ||
| 75 | &diag_file_ops, &diag_cdev, &diag_class_dev); | ||
| 76 | } | ||
| 77 | |||
| 78 | void ipath_diag_cleanup(void) | ||
| 79 | { | ||
| 80 | ipath_cdev_cleanup(&diag_cdev, &diag_class_dev); | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * ipath_read_umem64 - read a 64-bit quantity from the chip into user space | ||
| 85 | * @dd: the infinipath device | ||
| 86 | * @uaddr: the location to store the data in user memory | ||
| 87 | * @caddr: the source chip address (full pointer, not offset) | ||
| 88 | * @count: number of bytes to copy (multiple of 32 bits) | ||
| 89 | * | ||
| 90 | * This function also localizes all chip memory accesses. | ||
| 91 | * The copy should be written such that we read full cacheline packets | ||
| 92 | * from the chip. This is usually used for a single qword | ||
| 93 | * | ||
| 94 | * NOTE: This assumes the chip address is 64-bit aligned. | ||
| 95 | */ | ||
| 96 | static int ipath_read_umem64(struct ipath_devdata *dd, void __user *uaddr, | ||
| 97 | const void __iomem *caddr, size_t count) | ||
| 98 | { | ||
| 99 | const u64 __iomem *reg_addr = caddr; | ||
| 100 | const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64)); | ||
| 101 | int ret; | ||
| 102 | |||
| 103 | /* not very efficient, but it works for now */ | ||
| 104 | if (reg_addr < dd->ipath_kregbase || | ||
| 105 | reg_end > dd->ipath_kregend) { | ||
| 106 | ret = -EINVAL; | ||
| 107 | goto bail; | ||
| 108 | } | ||
| 109 | while (reg_addr < reg_end) { | ||
| 110 | u64 data = readq(reg_addr); | ||
| 111 | if (copy_to_user(uaddr, &data, sizeof(u64))) { | ||
| 112 | ret = -EFAULT; | ||
| 113 | goto bail; | ||
| 114 | } | ||
| 115 | reg_addr++; | ||
| 116 | uaddr++; | ||
| 117 | } | ||
| 118 | ret = 0; | ||
| 119 | bail: | ||
| 120 | return ret; | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * ipath_write_umem64 - write a 64-bit quantity to the chip from user space | ||
| 125 | * @dd: the infinipath device | ||
| 126 | * @caddr: the destination chip address (full pointer, not offset) | ||
| 127 | * @uaddr: the source of the data in user memory | ||
| 128 | * @count: the number of bytes to copy (multiple of 32 bits) | ||
| 129 | * | ||
| 130 | * This is usually used for a single qword | ||
| 131 | * NOTE: This assumes the chip address is 64-bit aligned. | ||
| 132 | */ | ||
| 133 | |||
| 134 | static int ipath_write_umem64(struct ipath_devdata *dd, void __iomem *caddr, | ||
| 135 | const void __user *uaddr, size_t count) | ||
| 136 | { | ||
| 137 | u64 __iomem *reg_addr = caddr; | ||
| 138 | const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64)); | ||
| 139 | int ret; | ||
| 140 | |||
| 141 | /* not very efficient, but it works for now */ | ||
| 142 | if (reg_addr < dd->ipath_kregbase || | ||
| 143 | reg_end > dd->ipath_kregend) { | ||
| 144 | ret = -EINVAL; | ||
| 145 | goto bail; | ||
| 146 | } | ||
| 147 | while (reg_addr < reg_end) { | ||
| 148 | u64 data; | ||
| 149 | if (copy_from_user(&data, uaddr, sizeof(data))) { | ||
| 150 | ret = -EFAULT; | ||
| 151 | goto bail; | ||
| 152 | } | ||
| 153 | writeq(data, reg_addr); | ||
| 154 | |||
| 155 | reg_addr++; | ||
| 156 | uaddr++; | ||
| 157 | } | ||
| 158 | ret = 0; | ||
| 159 | bail: | ||
| 160 | return ret; | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | ||
| 164 | * ipath_read_umem32 - read a 32-bit quantity from the chip into user space | ||
| 165 | * @dd: the infinipath device | ||
| 166 | * @uaddr: the location to store the data in user memory | ||
| 167 | * @caddr: the source chip address (full pointer, not offset) | ||
| 168 | * @count: number of bytes to copy | ||
| 169 | * | ||
| 170 | * read 32 bit values, not 64 bit; for memories that only | ||
| 171 | * support 32 bit reads; usually a single dword. | ||
| 172 | */ | ||
| 173 | static int ipath_read_umem32(struct ipath_devdata *dd, void __user *uaddr, | ||
| 174 | const void __iomem *caddr, size_t count) | ||
| 175 | { | ||
| 176 | const u32 __iomem *reg_addr = caddr; | ||
| 177 | const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32)); | ||
| 178 | int ret; | ||
| 179 | |||
| 180 | if (reg_addr < (u32 __iomem *) dd->ipath_kregbase || | ||
| 181 | reg_end > (u32 __iomem *) dd->ipath_kregend) { | ||
| 182 | ret = -EINVAL; | ||
| 183 | goto bail; | ||
| 184 | } | ||
| 185 | /* not very efficient, but it works for now */ | ||
| 186 | while (reg_addr < reg_end) { | ||
| 187 | u32 data = readl(reg_addr); | ||
| 188 | if (copy_to_user(uaddr, &data, sizeof(data))) { | ||
| 189 | ret = -EFAULT; | ||
| 190 | goto bail; | ||
| 191 | } | ||
| 192 | |||
| 193 | reg_addr++; | ||
| 194 | uaddr++; | ||
| 195 | } | ||
| 196 | ret = 0; | ||
| 197 | bail: | ||
| 198 | return ret; | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * ipath_write_umem32 - write a 32-bit quantity to the chip from user space | ||
| 203 | * @dd: the infinipath device | ||
| 204 | * @caddr: the destination chip address (full pointer, not offset) | ||
| 205 | * @uaddr: the source of the data in user memory | ||
| 206 | * @count: number of bytes to copy | ||
| 207 | * | ||
| 208 | * write 32 bit values, not 64 bit; for memories that only | ||
| 209 | * support 32 bit write; usually a single dword. | ||
| 210 | */ | ||
| 211 | |||
| 212 | static int ipath_write_umem32(struct ipath_devdata *dd, void __iomem *caddr, | ||
| 213 | const void __user *uaddr, size_t count) | ||
| 214 | { | ||
| 215 | u32 __iomem *reg_addr = caddr; | ||
| 216 | const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32)); | ||
| 217 | int ret; | ||
| 218 | |||
| 219 | if (reg_addr < (u32 __iomem *) dd->ipath_kregbase || | ||
| 220 | reg_end > (u32 __iomem *) dd->ipath_kregend) { | ||
| 221 | ret = -EINVAL; | ||
| 222 | goto bail; | ||
| 223 | } | ||
| 224 | while (reg_addr < reg_end) { | ||
| 225 | u32 data; | ||
| 226 | if (copy_from_user(&data, uaddr, sizeof(data))) { | ||
| 227 | ret = -EFAULT; | ||
| 228 | goto bail; | ||
| 229 | } | ||
| 230 | writel(data, reg_addr); | ||
| 231 | |||
| 232 | reg_addr++; | ||
| 233 | uaddr++; | ||
| 234 | } | ||
| 235 | ret = 0; | ||
| 236 | bail: | ||
| 237 | return ret; | ||
| 238 | } | ||
| 239 | |||
| 240 | static int ipath_diag_open(struct inode *in, struct file *fp) | ||
| 241 | { | ||
| 242 | struct ipath_devdata *dd; | ||
| 243 | int unit = 0; /* XXX this is bogus */ | ||
| 244 | unsigned long flags; | ||
| 245 | int ret; | ||
| 246 | |||
| 247 | dd = ipath_lookup(unit); | ||
| 248 | |||
| 249 | mutex_lock(&ipath_mutex); | ||
| 250 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 251 | |||
| 252 | if (ipath_diag_inuse) { | ||
| 253 | ret = -EBUSY; | ||
| 254 | goto bail; | ||
| 255 | } | ||
| 256 | |||
| 257 | list_for_each_entry(dd, &ipath_dev_list, ipath_list) { | ||
| 258 | /* | ||
| 259 | * we need at least one infinipath device to be present | ||
| 260 | * (don't use INITTED, because we want to be able to open | ||
| 261 | * even if device is in freeze mode, which cleared INITTED). | ||
| 262 | * There is a small amount of risk to this, which is why we | ||
| 263 | * also verify kregbase is set. | ||
| 264 | */ | ||
| 265 | |||
| 266 | if (!(dd->ipath_flags & IPATH_PRESENT) || | ||
| 267 | !dd->ipath_kregbase) | ||
| 268 | continue; | ||
| 269 | |||
| 270 | ipath_diag_inuse = 1; | ||
| 271 | diag_set_link = 0; | ||
| 272 | ret = 0; | ||
| 273 | goto bail; | ||
| 274 | } | ||
| 275 | |||
| 276 | ret = -ENODEV; | ||
| 277 | |||
| 278 | bail: | ||
| 279 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 280 | mutex_unlock(&ipath_mutex); | ||
| 281 | |||
| 282 | /* Only expose a way to reset the device if we | ||
| 283 | make it into diag mode. */ | ||
| 284 | if (ret == 0) | ||
| 285 | ipath_expose_reset(&dd->pcidev->dev); | ||
| 286 | |||
| 287 | return ret; | ||
| 288 | } | ||
| 289 | |||
| 290 | static int ipath_diag_release(struct inode *i, struct file *f) | ||
| 291 | { | ||
| 292 | mutex_lock(&ipath_mutex); | ||
| 293 | ipath_diag_inuse = 0; | ||
| 294 | mutex_unlock(&ipath_mutex); | ||
| 295 | return 0; | ||
| 296 | } | ||
| 297 | |||
| 298 | static ssize_t ipath_diag_read(struct file *fp, char __user *data, | ||
| 299 | size_t count, loff_t *off) | ||
| 300 | { | ||
| 301 | int unit = 0; /* XXX provide for reads on other units some day */ | ||
| 302 | struct ipath_devdata *dd; | ||
| 303 | void __iomem *kreg_base; | ||
| 304 | ssize_t ret; | ||
| 305 | |||
| 306 | dd = ipath_lookup(unit); | ||
| 307 | if (!dd) { | ||
| 308 | ret = -ENODEV; | ||
| 309 | goto bail; | ||
| 310 | } | ||
| 311 | |||
| 312 | kreg_base = dd->ipath_kregbase; | ||
| 313 | |||
| 314 | if (count == 0) | ||
| 315 | ret = 0; | ||
| 316 | else if ((count % 4) || (*off % 4)) | ||
| 317 | /* address or length is not 32-bit aligned, hence invalid */ | ||
| 318 | ret = -EINVAL; | ||
| 319 | else if ((count % 8) || (*off % 8)) | ||
| 320 | /* address or length not 64-bit aligned; do 32-bit reads */ | ||
| 321 | ret = ipath_read_umem32(dd, data, kreg_base + *off, count); | ||
| 322 | else | ||
| 323 | ret = ipath_read_umem64(dd, data, kreg_base + *off, count); | ||
| 324 | |||
| 325 | if (ret >= 0) { | ||
| 326 | *off += count; | ||
| 327 | ret = count; | ||
| 328 | } | ||
| 329 | |||
| 330 | bail: | ||
| 331 | return ret; | ||
| 332 | } | ||
| 333 | |||
| 334 | static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | ||
| 335 | size_t count, loff_t *off) | ||
| 336 | { | ||
| 337 | int unit = 0; /* XXX this is bogus */ | ||
| 338 | struct ipath_devdata *dd; | ||
| 339 | void __iomem *kreg_base; | ||
| 340 | ssize_t ret; | ||
| 341 | |||
| 342 | dd = ipath_lookup(unit); | ||
| 343 | if (!dd) { | ||
| 344 | ret = -ENODEV; | ||
| 345 | goto bail; | ||
| 346 | } | ||
| 347 | kreg_base = dd->ipath_kregbase; | ||
| 348 | |||
| 349 | if (count == 0) | ||
| 350 | ret = 0; | ||
| 351 | else if ((count % 4) || (*off % 4)) | ||
| 352 | /* address or length is not 32-bit aligned, hence invalid */ | ||
| 353 | ret = -EINVAL; | ||
| 354 | else if ((count % 8) || (*off % 8)) | ||
| 355 | /* address or length not 64-bit aligned; do 32-bit writes */ | ||
| 356 | ret = ipath_write_umem32(dd, kreg_base + *off, data, count); | ||
| 357 | else | ||
| 358 | ret = ipath_write_umem64(dd, kreg_base + *off, data, count); | ||
| 359 | |||
| 360 | if (ret >= 0) { | ||
| 361 | *off += count; | ||
| 362 | ret = count; | ||
| 363 | } | ||
| 364 | |||
| 365 | bail: | ||
| 366 | return ret; | ||
| 367 | } | ||
| 368 | |||
| 369 | void ipath_diag_bringup_link(struct ipath_devdata *dd) | ||
| 370 | { | ||
| 371 | if (diag_set_link || (dd->ipath_flags & IPATH_LINKACTIVE)) | ||
| 372 | return; | ||
| 373 | |||
| 374 | diag_set_link = 1; | ||
| 375 | ipath_cdbg(VERBOSE, "Trying to set to set link active for " | ||
| 376 | "diag pkt\n"); | ||
| 377 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKARM); | ||
| 378 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKACTIVE); | ||
| 379 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c new file mode 100644 index 000000000000..58a94efb0070 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
| @@ -0,0 +1,1983 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/spinlock.h> | ||
| 34 | #include <linux/idr.h> | ||
| 35 | #include <linux/pci.h> | ||
| 36 | #include <linux/delay.h> | ||
| 37 | #include <linux/netdevice.h> | ||
| 38 | #include <linux/vmalloc.h> | ||
| 39 | |||
| 40 | #include "ipath_kernel.h" | ||
| 41 | #include "ips_common.h" | ||
| 42 | #include "ipath_layer.h" | ||
| 43 | |||
| 44 | static void ipath_update_pio_bufs(struct ipath_devdata *); | ||
| 45 | |||
| 46 | const char *ipath_get_unit_name(int unit) | ||
| 47 | { | ||
| 48 | static char iname[16]; | ||
| 49 | snprintf(iname, sizeof iname, "infinipath%u", unit); | ||
| 50 | return iname; | ||
| 51 | } | ||
| 52 | |||
| 53 | EXPORT_SYMBOL_GPL(ipath_get_unit_name); | ||
| 54 | |||
| 55 | #define DRIVER_LOAD_MSG "PathScale " IPATH_DRV_NAME " loaded: " | ||
| 56 | #define PFX IPATH_DRV_NAME ": " | ||
| 57 | |||
| 58 | /* | ||
| 59 | * The size has to be longer than this string, so we can append | ||
| 60 | * board/chip information to it in the init code. | ||
| 61 | */ | ||
| 62 | const char ipath_core_version[] = IPATH_IDSTR "\n"; | ||
| 63 | |||
| 64 | static struct idr unit_table; | ||
| 65 | DEFINE_SPINLOCK(ipath_devs_lock); | ||
| 66 | LIST_HEAD(ipath_dev_list); | ||
| 67 | |||
| 68 | wait_queue_head_t ipath_sma_state_wait; | ||
| 69 | |||
| 70 | unsigned ipath_debug = __IPATH_INFO; | ||
| 71 | |||
| 72 | module_param_named(debug, ipath_debug, uint, S_IWUSR | S_IRUGO); | ||
| 73 | MODULE_PARM_DESC(debug, "mask for debug prints"); | ||
| 74 | EXPORT_SYMBOL_GPL(ipath_debug); | ||
| 75 | |||
| 76 | MODULE_LICENSE("GPL"); | ||
| 77 | MODULE_AUTHOR("PathScale <support@pathscale.com>"); | ||
| 78 | MODULE_DESCRIPTION("Pathscale InfiniPath driver"); | ||
| 79 | |||
| 80 | const char *ipath_ibcstatus_str[] = { | ||
| 81 | "Disabled", | ||
| 82 | "LinkUp", | ||
| 83 | "PollActive", | ||
| 84 | "PollQuiet", | ||
| 85 | "SleepDelay", | ||
| 86 | "SleepQuiet", | ||
| 87 | "LState6", /* unused */ | ||
| 88 | "LState7", /* unused */ | ||
| 89 | "CfgDebounce", | ||
| 90 | "CfgRcvfCfg", | ||
| 91 | "CfgWaitRmt", | ||
| 92 | "CfgIdle", | ||
| 93 | "RecovRetrain", | ||
| 94 | "LState0xD", /* unused */ | ||
| 95 | "RecovWaitRmt", | ||
| 96 | "RecovIdle", | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* | ||
| 100 | * These variables are initialized in the chip-specific files | ||
| 101 | * but are defined here. | ||
| 102 | */ | ||
| 103 | u16 ipath_gpio_sda_num, ipath_gpio_scl_num; | ||
| 104 | u64 ipath_gpio_sda, ipath_gpio_scl; | ||
| 105 | u64 infinipath_i_bitsextant; | ||
| 106 | ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant; | ||
| 107 | u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask; | ||
| 108 | |||
| 109 | static void __devexit ipath_remove_one(struct pci_dev *); | ||
| 110 | static int __devinit ipath_init_one(struct pci_dev *, | ||
| 111 | const struct pci_device_id *); | ||
| 112 | |||
| 113 | /* Only needed for registration, nothing else needs this info */ | ||
| 114 | #define PCI_VENDOR_ID_PATHSCALE 0x1fc1 | ||
| 115 | #define PCI_DEVICE_ID_INFINIPATH_HT 0xd | ||
| 116 | #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 | ||
| 117 | |||
| 118 | static const struct pci_device_id ipath_pci_tbl[] = { | ||
| 119 | {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, | ||
| 120 | PCI_DEVICE_ID_INFINIPATH_HT)}, | ||
| 121 | {PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, | ||
| 122 | PCI_DEVICE_ID_INFINIPATH_PE800)}, | ||
| 123 | }; | ||
| 124 | |||
| 125 | MODULE_DEVICE_TABLE(pci, ipath_pci_tbl); | ||
| 126 | |||
| 127 | static struct pci_driver ipath_driver = { | ||
| 128 | .name = IPATH_DRV_NAME, | ||
| 129 | .probe = ipath_init_one, | ||
| 130 | .remove = __devexit_p(ipath_remove_one), | ||
| 131 | .id_table = ipath_pci_tbl, | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* | ||
| 135 | * This is where port 0's rcvhdrtail register is written back; we also | ||
| 136 | * want nothing else sharing the cache line, so make it a cache line | ||
| 137 | * in size. Used for all units. | ||
| 138 | */ | ||
| 139 | volatile __le64 *ipath_port0_rcvhdrtail; | ||
| 140 | dma_addr_t ipath_port0_rcvhdrtail_dma; | ||
| 141 | static int port0_rcvhdrtail_refs; | ||
| 142 | |||
| 143 | static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev, | ||
| 144 | u32 *bar0, u32 *bar1) | ||
| 145 | { | ||
| 146 | int ret; | ||
| 147 | |||
| 148 | ret = pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); | ||
| 149 | if (ret) | ||
| 150 | ipath_dev_err(dd, "failed to read bar0 before enable: " | ||
| 151 | "error %d\n", -ret); | ||
| 152 | |||
| 153 | ret = pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, bar1); | ||
| 154 | if (ret) | ||
| 155 | ipath_dev_err(dd, "failed to read bar1 before enable: " | ||
| 156 | "error %d\n", -ret); | ||
| 157 | |||
| 158 | ipath_dbg("Read bar0 %x bar1 %x\n", *bar0, *bar1); | ||
| 159 | } | ||
| 160 | |||
| 161 | static void ipath_free_devdata(struct pci_dev *pdev, | ||
| 162 | struct ipath_devdata *dd) | ||
| 163 | { | ||
| 164 | unsigned long flags; | ||
| 165 | |||
| 166 | pci_set_drvdata(pdev, NULL); | ||
| 167 | |||
| 168 | if (dd->ipath_unit != -1) { | ||
| 169 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 170 | idr_remove(&unit_table, dd->ipath_unit); | ||
| 171 | list_del(&dd->ipath_list); | ||
| 172 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 173 | } | ||
| 174 | dma_free_coherent(&pdev->dev, sizeof(*dd), dd, dd->ipath_dma_addr); | ||
| 175 | } | ||
| 176 | |||
| 177 | static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev) | ||
| 178 | { | ||
| 179 | unsigned long flags; | ||
| 180 | struct ipath_devdata *dd; | ||
| 181 | dma_addr_t dma_addr; | ||
| 182 | int ret; | ||
| 183 | |||
| 184 | if (!idr_pre_get(&unit_table, GFP_KERNEL)) { | ||
| 185 | dd = ERR_PTR(-ENOMEM); | ||
| 186 | goto bail; | ||
| 187 | } | ||
| 188 | |||
| 189 | dd = dma_alloc_coherent(&pdev->dev, sizeof(*dd), &dma_addr, | ||
| 190 | GFP_KERNEL); | ||
| 191 | |||
| 192 | if (!dd) { | ||
| 193 | dd = ERR_PTR(-ENOMEM); | ||
| 194 | goto bail; | ||
| 195 | } | ||
| 196 | |||
| 197 | dd->ipath_dma_addr = dma_addr; | ||
| 198 | dd->ipath_unit = -1; | ||
| 199 | |||
| 200 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 201 | |||
| 202 | ret = idr_get_new(&unit_table, dd, &dd->ipath_unit); | ||
| 203 | if (ret < 0) { | ||
| 204 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 205 | ": Could not allocate unit ID: error %d\n", -ret); | ||
| 206 | ipath_free_devdata(pdev, dd); | ||
| 207 | dd = ERR_PTR(ret); | ||
| 208 | goto bail_unlock; | ||
| 209 | } | ||
| 210 | |||
| 211 | dd->pcidev = pdev; | ||
| 212 | pci_set_drvdata(pdev, dd); | ||
| 213 | |||
| 214 | list_add(&dd->ipath_list, &ipath_dev_list); | ||
| 215 | |||
| 216 | bail_unlock: | ||
| 217 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 218 | |||
| 219 | bail: | ||
| 220 | return dd; | ||
| 221 | } | ||
| 222 | |||
| 223 | static inline struct ipath_devdata *__ipath_lookup(int unit) | ||
| 224 | { | ||
| 225 | return idr_find(&unit_table, unit); | ||
| 226 | } | ||
| 227 | |||
| 228 | struct ipath_devdata *ipath_lookup(int unit) | ||
| 229 | { | ||
| 230 | struct ipath_devdata *dd; | ||
| 231 | unsigned long flags; | ||
| 232 | |||
| 233 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 234 | dd = __ipath_lookup(unit); | ||
| 235 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 236 | |||
| 237 | return dd; | ||
| 238 | } | ||
| 239 | |||
| 240 | int ipath_count_units(int *npresentp, int *nupp, u32 *maxportsp) | ||
| 241 | { | ||
| 242 | int nunits, npresent, nup; | ||
| 243 | struct ipath_devdata *dd; | ||
| 244 | unsigned long flags; | ||
| 245 | u32 maxports; | ||
| 246 | |||
| 247 | nunits = npresent = nup = maxports = 0; | ||
| 248 | |||
| 249 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 250 | |||
| 251 | list_for_each_entry(dd, &ipath_dev_list, ipath_list) { | ||
| 252 | nunits++; | ||
| 253 | if ((dd->ipath_flags & IPATH_PRESENT) && dd->ipath_kregbase) | ||
| 254 | npresent++; | ||
| 255 | if (dd->ipath_lid && | ||
| 256 | !(dd->ipath_flags & (IPATH_DISABLED | IPATH_LINKDOWN | ||
| 257 | | IPATH_LINKUNK))) | ||
| 258 | nup++; | ||
| 259 | if (dd->ipath_cfgports > maxports) | ||
| 260 | maxports = dd->ipath_cfgports; | ||
| 261 | } | ||
| 262 | |||
| 263 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 264 | |||
| 265 | if (npresentp) | ||
| 266 | *npresentp = npresent; | ||
| 267 | if (nupp) | ||
| 268 | *nupp = nup; | ||
| 269 | if (maxportsp) | ||
| 270 | *maxportsp = maxports; | ||
| 271 | |||
| 272 | return nunits; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int init_port0_rcvhdrtail(struct pci_dev *pdev) | ||
| 276 | { | ||
| 277 | int ret; | ||
| 278 | |||
| 279 | mutex_lock(&ipath_mutex); | ||
| 280 | |||
| 281 | if (!ipath_port0_rcvhdrtail) { | ||
| 282 | ipath_port0_rcvhdrtail = | ||
| 283 | dma_alloc_coherent(&pdev->dev, | ||
| 284 | IPATH_PORT0_RCVHDRTAIL_SIZE, | ||
| 285 | &ipath_port0_rcvhdrtail_dma, | ||
| 286 | GFP_KERNEL); | ||
| 287 | |||
| 288 | if (!ipath_port0_rcvhdrtail) { | ||
| 289 | ret = -ENOMEM; | ||
| 290 | goto bail; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | port0_rcvhdrtail_refs++; | ||
| 294 | ret = 0; | ||
| 295 | |||
| 296 | bail: | ||
| 297 | mutex_unlock(&ipath_mutex); | ||
| 298 | |||
| 299 | return ret; | ||
| 300 | } | ||
| 301 | |||
| 302 | static void cleanup_port0_rcvhdrtail(struct pci_dev *pdev) | ||
| 303 | { | ||
| 304 | mutex_lock(&ipath_mutex); | ||
| 305 | |||
| 306 | if (!--port0_rcvhdrtail_refs) { | ||
| 307 | dma_free_coherent(&pdev->dev, IPATH_PORT0_RCVHDRTAIL_SIZE, | ||
| 308 | (void *) ipath_port0_rcvhdrtail, | ||
| 309 | ipath_port0_rcvhdrtail_dma); | ||
| 310 | ipath_port0_rcvhdrtail = NULL; | ||
| 311 | } | ||
| 312 | |||
| 313 | mutex_unlock(&ipath_mutex); | ||
| 314 | } | ||
| 315 | |||
| 316 | /* | ||
| 317 | * These next two routines are placeholders in case we don't have per-arch | ||
| 318 | * code for controlling write combining. If explicit control of write | ||
| 319 | * combining is not available, performance will probably be awful. | ||
| 320 | */ | ||
| 321 | |||
| 322 | int __attribute__((weak)) ipath_enable_wc(struct ipath_devdata *dd) | ||
| 323 | { | ||
| 324 | return -EOPNOTSUPP; | ||
| 325 | } | ||
| 326 | |||
| 327 | void __attribute__((weak)) ipath_disable_wc(struct ipath_devdata *dd) | ||
| 328 | { | ||
| 329 | } | ||
| 330 | |||
| 331 | static int __devinit ipath_init_one(struct pci_dev *pdev, | ||
| 332 | const struct pci_device_id *ent) | ||
| 333 | { | ||
| 334 | int ret, len, j; | ||
| 335 | struct ipath_devdata *dd; | ||
| 336 | unsigned long long addr; | ||
| 337 | u32 bar0 = 0, bar1 = 0; | ||
| 338 | u8 rev; | ||
| 339 | |||
| 340 | ret = init_port0_rcvhdrtail(pdev); | ||
| 341 | if (ret < 0) { | ||
| 342 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 343 | ": Could not allocate port0_rcvhdrtail: error %d\n", | ||
| 344 | -ret); | ||
| 345 | goto bail; | ||
| 346 | } | ||
| 347 | |||
| 348 | dd = ipath_alloc_devdata(pdev); | ||
| 349 | if (IS_ERR(dd)) { | ||
| 350 | ret = PTR_ERR(dd); | ||
| 351 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 352 | ": Could not allocate devdata: error %d\n", -ret); | ||
| 353 | goto bail_rcvhdrtail; | ||
| 354 | } | ||
| 355 | |||
| 356 | ipath_cdbg(VERBOSE, "initializing unit #%u\n", dd->ipath_unit); | ||
| 357 | |||
| 358 | read_bars(dd, pdev, &bar0, &bar1); | ||
| 359 | |||
| 360 | ret = pci_enable_device(pdev); | ||
| 361 | if (ret) { | ||
| 362 | /* This can happen iff: | ||
| 363 | * | ||
| 364 | * We did a chip reset, and then failed to reprogram the | ||
| 365 | * BAR, or the chip reset due to an internal error. We then | ||
| 366 | * unloaded the driver and reloaded it. | ||
| 367 | * | ||
| 368 | * Both reset cases set the BAR back to initial state. For | ||
| 369 | * the latter case, the AER sticky error bit at offset 0x718 | ||
| 370 | * should be set, but the Linux kernel doesn't yet know | ||
| 371 | * about that, it appears. If the original BAR was retained | ||
| 372 | * in the kernel data structures, this may be OK. | ||
| 373 | */ | ||
| 374 | ipath_dev_err(dd, "enable unit %d failed: error %d\n", | ||
| 375 | dd->ipath_unit, -ret); | ||
| 376 | goto bail_devdata; | ||
| 377 | } | ||
| 378 | addr = pci_resource_start(pdev, 0); | ||
| 379 | len = pci_resource_len(pdev, 0); | ||
| 380 | ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %x, vend %x/%x " | ||
| 381 | "driver_data %lx\n", addr, len, pdev->irq, ent->vendor, | ||
| 382 | ent->device, ent->driver_data); | ||
| 383 | |||
| 384 | read_bars(dd, pdev, &bar0, &bar1); | ||
| 385 | |||
| 386 | if (!bar1 && !(bar0 & ~0xf)) { | ||
| 387 | if (addr) { | ||
| 388 | dev_info(&pdev->dev, "BAR is 0 (probable RESET), " | ||
| 389 | "rewriting as %llx\n", addr); | ||
| 390 | ret = pci_write_config_dword( | ||
| 391 | pdev, PCI_BASE_ADDRESS_0, addr); | ||
| 392 | if (ret) { | ||
| 393 | ipath_dev_err(dd, "rewrite of BAR0 " | ||
| 394 | "failed: err %d\n", -ret); | ||
| 395 | goto bail_disable; | ||
| 396 | } | ||
| 397 | ret = pci_write_config_dword( | ||
| 398 | pdev, PCI_BASE_ADDRESS_1, addr >> 32); | ||
| 399 | if (ret) { | ||
| 400 | ipath_dev_err(dd, "rewrite of BAR1 " | ||
| 401 | "failed: err %d\n", -ret); | ||
| 402 | goto bail_disable; | ||
| 403 | } | ||
| 404 | } else { | ||
| 405 | ipath_dev_err(dd, "BAR is 0 (probable RESET), " | ||
| 406 | "not usable until reboot\n"); | ||
| 407 | ret = -ENODEV; | ||
| 408 | goto bail_disable; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | ret = pci_request_regions(pdev, IPATH_DRV_NAME); | ||
| 413 | if (ret) { | ||
| 414 | dev_info(&pdev->dev, "pci_request_regions unit %u fails: " | ||
| 415 | "err %d\n", dd->ipath_unit, -ret); | ||
| 416 | goto bail_disable; | ||
| 417 | } | ||
| 418 | |||
| 419 | ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | ||
| 420 | if (ret) { | ||
| 421 | dev_info(&pdev->dev, "pci_set_dma_mask unit %u " | ||
| 422 | "fails: %d\n", dd->ipath_unit, ret); | ||
| 423 | goto bail_regions; | ||
| 424 | } | ||
| 425 | |||
| 426 | pci_set_master(pdev); | ||
| 427 | |||
| 428 | /* | ||
| 429 | * Save BARs to rewrite after device reset. Save all 64 bits of | ||
| 430 | * BAR, just in case. | ||
| 431 | */ | ||
| 432 | dd->ipath_pcibar0 = addr; | ||
| 433 | dd->ipath_pcibar1 = addr >> 32; | ||
| 434 | dd->ipath_deviceid = ent->device; /* save for later use */ | ||
| 435 | dd->ipath_vendorid = ent->vendor; | ||
| 436 | |||
| 437 | /* setup the chip-specific functions, as early as possible. */ | ||
| 438 | switch (ent->device) { | ||
| 439 | case PCI_DEVICE_ID_INFINIPATH_HT: | ||
| 440 | ipath_init_ht400_funcs(dd); | ||
| 441 | break; | ||
| 442 | case PCI_DEVICE_ID_INFINIPATH_PE800: | ||
| 443 | ipath_init_pe800_funcs(dd); | ||
| 444 | break; | ||
| 445 | default: | ||
| 446 | ipath_dev_err(dd, "Found unknown PathScale deviceid 0x%x, " | ||
| 447 | "failing\n", ent->device); | ||
| 448 | return -ENODEV; | ||
| 449 | } | ||
| 450 | |||
| 451 | for (j = 0; j < 6; j++) { | ||
| 452 | if (!pdev->resource[j].start) | ||
| 453 | continue; | ||
| 454 | ipath_cdbg(VERBOSE, "BAR %d start %lx, end %lx, len %lx\n", | ||
| 455 | j, pdev->resource[j].start, | ||
| 456 | pdev->resource[j].end, | ||
| 457 | pci_resource_len(pdev, j)); | ||
| 458 | } | ||
| 459 | |||
| 460 | if (!addr) { | ||
| 461 | ipath_dev_err(dd, "No valid address in BAR 0!\n"); | ||
| 462 | ret = -ENODEV; | ||
| 463 | goto bail_regions; | ||
| 464 | } | ||
| 465 | |||
| 466 | dd->ipath_deviceid = ent->device; /* save for later use */ | ||
| 467 | dd->ipath_vendorid = ent->vendor; | ||
| 468 | |||
| 469 | ret = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); | ||
| 470 | if (ret) { | ||
| 471 | ipath_dev_err(dd, "Failed to read PCI revision ID unit " | ||
| 472 | "%u: err %d\n", dd->ipath_unit, -ret); | ||
| 473 | goto bail_regions; /* shouldn't ever happen */ | ||
| 474 | } | ||
| 475 | dd->ipath_pcirev = rev; | ||
| 476 | |||
| 477 | dd->ipath_kregbase = ioremap_nocache(addr, len); | ||
| 478 | |||
| 479 | if (!dd->ipath_kregbase) { | ||
| 480 | ipath_dbg("Unable to map io addr %llx to kvirt, failing\n", | ||
| 481 | addr); | ||
| 482 | ret = -ENOMEM; | ||
| 483 | goto bail_iounmap; | ||
| 484 | } | ||
| 485 | dd->ipath_kregend = (u64 __iomem *) | ||
| 486 | ((void __iomem *)dd->ipath_kregbase + len); | ||
| 487 | dd->ipath_physaddr = addr; /* used for io_remap, etc. */ | ||
| 488 | /* for user mmap */ | ||
| 489 | dd->ipath_kregvirt = (u64 __iomem *) phys_to_virt(addr); | ||
| 490 | ipath_cdbg(VERBOSE, "mapped io addr %llx to kregbase %p " | ||
| 491 | "kregvirt %p\n", addr, dd->ipath_kregbase, | ||
| 492 | dd->ipath_kregvirt); | ||
| 493 | |||
| 494 | /* | ||
| 495 | * clear ipath_flags here instead of in ipath_init_chip as it is set | ||
| 496 | * by ipath_setup_htconfig. | ||
| 497 | */ | ||
| 498 | dd->ipath_flags = 0; | ||
| 499 | |||
| 500 | if (dd->ipath_f_bus(dd, pdev)) | ||
| 501 | ipath_dev_err(dd, "Failed to setup config space; " | ||
| 502 | "continuing anyway\n"); | ||
| 503 | |||
| 504 | /* | ||
| 505 | * set up our interrupt handler; SA_SHIRQ probably not needed, | ||
| 506 | * since MSI interrupts shouldn't be shared but won't hurt for now. | ||
| 507 | * check 0 irq after we return from chip-specific bus setup, since | ||
| 508 | * that can affect this due to setup | ||
| 509 | */ | ||
| 510 | if (!pdev->irq) | ||
| 511 | ipath_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " | ||
| 512 | "work\n"); | ||
| 513 | else { | ||
| 514 | ret = request_irq(pdev->irq, ipath_intr, SA_SHIRQ, | ||
| 515 | IPATH_DRV_NAME, dd); | ||
| 516 | if (ret) { | ||
| 517 | ipath_dev_err(dd, "Couldn't setup irq handler, " | ||
| 518 | "irq=%u: %d\n", pdev->irq, ret); | ||
| 519 | goto bail_iounmap; | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | ret = ipath_init_chip(dd, 0); /* do the chip-specific init */ | ||
| 524 | if (ret) | ||
| 525 | goto bail_iounmap; | ||
| 526 | |||
| 527 | ret = ipath_enable_wc(dd); | ||
| 528 | |||
| 529 | if (ret) { | ||
| 530 | ipath_dev_err(dd, "Write combining not enabled " | ||
| 531 | "(err %d): performance may be poor\n", | ||
| 532 | -ret); | ||
| 533 | ret = 0; | ||
| 534 | } | ||
| 535 | |||
| 536 | ipath_device_create_group(&pdev->dev, dd); | ||
| 537 | ipathfs_add_device(dd); | ||
| 538 | ipath_user_add(dd); | ||
| 539 | ipath_layer_add(dd); | ||
| 540 | |||
| 541 | goto bail; | ||
| 542 | |||
| 543 | bail_iounmap: | ||
| 544 | iounmap((volatile void __iomem *) dd->ipath_kregbase); | ||
| 545 | |||
| 546 | bail_regions: | ||
| 547 | pci_release_regions(pdev); | ||
| 548 | |||
| 549 | bail_disable: | ||
| 550 | pci_disable_device(pdev); | ||
| 551 | |||
| 552 | bail_devdata: | ||
| 553 | ipath_free_devdata(pdev, dd); | ||
| 554 | |||
| 555 | bail_rcvhdrtail: | ||
| 556 | cleanup_port0_rcvhdrtail(pdev); | ||
| 557 | |||
| 558 | bail: | ||
| 559 | return ret; | ||
| 560 | } | ||
| 561 | |||
| 562 | static void __devexit ipath_remove_one(struct pci_dev *pdev) | ||
| 563 | { | ||
| 564 | struct ipath_devdata *dd; | ||
| 565 | |||
| 566 | ipath_cdbg(VERBOSE, "removing, pdev=%p\n", pdev); | ||
| 567 | if (!pdev) | ||
| 568 | return; | ||
| 569 | |||
| 570 | dd = pci_get_drvdata(pdev); | ||
| 571 | ipath_layer_del(dd); | ||
| 572 | ipath_user_del(dd); | ||
| 573 | ipathfs_remove_device(dd); | ||
| 574 | ipath_device_remove_group(&pdev->dev, dd); | ||
| 575 | ipath_cdbg(VERBOSE, "Releasing pci memory regions, dd %p, " | ||
| 576 | "unit %u\n", dd, (u32) dd->ipath_unit); | ||
| 577 | if (dd->ipath_kregbase) { | ||
| 578 | ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n", | ||
| 579 | dd->ipath_kregbase); | ||
| 580 | iounmap((volatile void __iomem *) dd->ipath_kregbase); | ||
| 581 | dd->ipath_kregbase = NULL; | ||
| 582 | } | ||
| 583 | pci_release_regions(pdev); | ||
| 584 | ipath_cdbg(VERBOSE, "calling pci_disable_device\n"); | ||
| 585 | pci_disable_device(pdev); | ||
| 586 | |||
| 587 | ipath_free_devdata(pdev, dd); | ||
| 588 | cleanup_port0_rcvhdrtail(pdev); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* general driver use */ | ||
| 592 | DEFINE_MUTEX(ipath_mutex); | ||
| 593 | |||
| 594 | static DEFINE_SPINLOCK(ipath_pioavail_lock); | ||
| 595 | |||
| 596 | /** | ||
| 597 | * ipath_disarm_piobufs - cancel a range of PIO buffers | ||
| 598 | * @dd: the infinipath device | ||
| 599 | * @first: the first PIO buffer to cancel | ||
| 600 | * @cnt: the number of PIO buffers to cancel | ||
| 601 | * | ||
| 602 | * cancel a range of PIO buffers, used when they might be armed, but | ||
| 603 | * not triggered. Used at init to ensure buffer state, and also user | ||
| 604 | * process close, in case it died while writing to a PIO buffer | ||
| 605 | * Also after errors. | ||
| 606 | */ | ||
| 607 | void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, | ||
| 608 | unsigned cnt) | ||
| 609 | { | ||
| 610 | unsigned i, last = first + cnt; | ||
| 611 | u64 sendctrl, sendorig; | ||
| 612 | |||
| 613 | ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); | ||
| 614 | sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM; | ||
| 615 | for (i = first; i < last; i++) { | ||
| 616 | sendctrl = sendorig | | ||
| 617 | (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); | ||
| 618 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 619 | sendctrl); | ||
| 620 | } | ||
| 621 | |||
| 622 | /* | ||
| 623 | * Write it again with current value, in case ipath_sendctrl changed | ||
| 624 | * while we were looping; no critical bits that would require | ||
| 625 | * locking. | ||
| 626 | * | ||
| 627 | * Write a 0, and then the original value, reading scratch in | ||
| 628 | * between. This seems to avoid a chip timing race that causes | ||
| 629 | * pioavail updates to memory to stop. | ||
| 630 | */ | ||
| 631 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 632 | 0); | ||
| 633 | sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 634 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 635 | dd->ipath_sendctrl); | ||
| 636 | } | ||
| 637 | |||
| 638 | /** | ||
| 639 | * ipath_wait_linkstate - wait for an IB link state change to occur | ||
| 640 | * @dd: the infinipath device | ||
| 641 | * @state: the state to wait for | ||
| 642 | * @msecs: the number of milliseconds to wait | ||
| 643 | * | ||
| 644 | * wait up to msecs milliseconds for IB link state change to occur for | ||
| 645 | * now, take the easy polling route. Currently used only by | ||
| 646 | * ipath_layer_set_linkstate. Returns 0 if state reached, otherwise | ||
| 647 | * -ETIMEDOUT state can have multiple states set, for any of several | ||
| 648 | * transitions. | ||
| 649 | */ | ||
| 650 | int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs) | ||
| 651 | { | ||
| 652 | dd->ipath_sma_state_wanted = state; | ||
| 653 | wait_event_interruptible_timeout(ipath_sma_state_wait, | ||
| 654 | (dd->ipath_flags & state), | ||
| 655 | msecs_to_jiffies(msecs)); | ||
| 656 | dd->ipath_sma_state_wanted = 0; | ||
| 657 | |||
| 658 | if (!(dd->ipath_flags & state)) { | ||
| 659 | u64 val; | ||
| 660 | ipath_cdbg(SMA, "Didn't reach linkstate %s within %u ms\n", | ||
| 661 | /* test INIT ahead of DOWN, both can be set */ | ||
| 662 | (state & IPATH_LINKINIT) ? "INIT" : | ||
| 663 | ((state & IPATH_LINKDOWN) ? "DOWN" : | ||
| 664 | ((state & IPATH_LINKARMED) ? "ARM" : "ACTIVE")), | ||
| 665 | msecs); | ||
| 666 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); | ||
| 667 | ipath_cdbg(VERBOSE, "ibcc=%llx ibcstatus=%llx (%s)\n", | ||
| 668 | (unsigned long long) ipath_read_kreg64( | ||
| 669 | dd, dd->ipath_kregs->kr_ibcctrl), | ||
| 670 | (unsigned long long) val, | ||
| 671 | ipath_ibcstatus_str[val & 0xf]); | ||
| 672 | } | ||
| 673 | return (dd->ipath_flags & state) ? 0 : -ETIMEDOUT; | ||
| 674 | } | ||
| 675 | |||
| 676 | void ipath_decode_err(char *buf, size_t blen, ipath_err_t err) | ||
| 677 | { | ||
| 678 | *buf = '\0'; | ||
| 679 | if (err & INFINIPATH_E_RHDRLEN) | ||
| 680 | strlcat(buf, "rhdrlen ", blen); | ||
| 681 | if (err & INFINIPATH_E_RBADTID) | ||
| 682 | strlcat(buf, "rbadtid ", blen); | ||
| 683 | if (err & INFINIPATH_E_RBADVERSION) | ||
| 684 | strlcat(buf, "rbadversion ", blen); | ||
| 685 | if (err & INFINIPATH_E_RHDR) | ||
| 686 | strlcat(buf, "rhdr ", blen); | ||
| 687 | if (err & INFINIPATH_E_RLONGPKTLEN) | ||
| 688 | strlcat(buf, "rlongpktlen ", blen); | ||
| 689 | if (err & INFINIPATH_E_RSHORTPKTLEN) | ||
| 690 | strlcat(buf, "rshortpktlen ", blen); | ||
| 691 | if (err & INFINIPATH_E_RMAXPKTLEN) | ||
| 692 | strlcat(buf, "rmaxpktlen ", blen); | ||
| 693 | if (err & INFINIPATH_E_RMINPKTLEN) | ||
| 694 | strlcat(buf, "rminpktlen ", blen); | ||
| 695 | if (err & INFINIPATH_E_RFORMATERR) | ||
| 696 | strlcat(buf, "rformaterr ", blen); | ||
| 697 | if (err & INFINIPATH_E_RUNSUPVL) | ||
| 698 | strlcat(buf, "runsupvl ", blen); | ||
| 699 | if (err & INFINIPATH_E_RUNEXPCHAR) | ||
| 700 | strlcat(buf, "runexpchar ", blen); | ||
| 701 | if (err & INFINIPATH_E_RIBFLOW) | ||
| 702 | strlcat(buf, "ribflow ", blen); | ||
| 703 | if (err & INFINIPATH_E_REBP) | ||
| 704 | strlcat(buf, "EBP ", blen); | ||
| 705 | if (err & INFINIPATH_E_SUNDERRUN) | ||
| 706 | strlcat(buf, "sunderrun ", blen); | ||
| 707 | if (err & INFINIPATH_E_SPIOARMLAUNCH) | ||
| 708 | strlcat(buf, "spioarmlaunch ", blen); | ||
| 709 | if (err & INFINIPATH_E_SUNEXPERRPKTNUM) | ||
| 710 | strlcat(buf, "sunexperrpktnum ", blen); | ||
| 711 | if (err & INFINIPATH_E_SDROPPEDDATAPKT) | ||
| 712 | strlcat(buf, "sdroppeddatapkt ", blen); | ||
| 713 | if (err & INFINIPATH_E_SDROPPEDSMPPKT) | ||
| 714 | strlcat(buf, "sdroppedsmppkt ", blen); | ||
| 715 | if (err & INFINIPATH_E_SMAXPKTLEN) | ||
| 716 | strlcat(buf, "smaxpktlen ", blen); | ||
| 717 | if (err & INFINIPATH_E_SMINPKTLEN) | ||
| 718 | strlcat(buf, "sminpktlen ", blen); | ||
| 719 | if (err & INFINIPATH_E_SUNSUPVL) | ||
| 720 | strlcat(buf, "sunsupVL ", blen); | ||
| 721 | if (err & INFINIPATH_E_SPKTLEN) | ||
| 722 | strlcat(buf, "spktlen ", blen); | ||
| 723 | if (err & INFINIPATH_E_INVALIDADDR) | ||
| 724 | strlcat(buf, "invalidaddr ", blen); | ||
| 725 | if (err & INFINIPATH_E_RICRC) | ||
| 726 | strlcat(buf, "CRC ", blen); | ||
| 727 | if (err & INFINIPATH_E_RVCRC) | ||
| 728 | strlcat(buf, "VCRC ", blen); | ||
| 729 | if (err & INFINIPATH_E_RRCVEGRFULL) | ||
| 730 | strlcat(buf, "rcvegrfull ", blen); | ||
| 731 | if (err & INFINIPATH_E_RRCVHDRFULL) | ||
| 732 | strlcat(buf, "rcvhdrfull ", blen); | ||
| 733 | if (err & INFINIPATH_E_IBSTATUSCHANGED) | ||
| 734 | strlcat(buf, "ibcstatuschg ", blen); | ||
| 735 | if (err & INFINIPATH_E_RIBLOSTLINK) | ||
| 736 | strlcat(buf, "riblostlink ", blen); | ||
| 737 | if (err & INFINIPATH_E_HARDWARE) | ||
| 738 | strlcat(buf, "hardware ", blen); | ||
| 739 | if (err & INFINIPATH_E_RESET) | ||
| 740 | strlcat(buf, "reset ", blen); | ||
| 741 | } | ||
| 742 | |||
| 743 | /** | ||
| 744 | * get_rhf_errstring - decode RHF errors | ||
| 745 | * @err: the err number | ||
| 746 | * @msg: the output buffer | ||
| 747 | * @len: the length of the output buffer | ||
| 748 | * | ||
| 749 | * only used one place now, may want more later | ||
| 750 | */ | ||
| 751 | static void get_rhf_errstring(u32 err, char *msg, size_t len) | ||
| 752 | { | ||
| 753 | /* if no errors, and so don't need to check what's first */ | ||
| 754 | *msg = '\0'; | ||
| 755 | |||
| 756 | if (err & INFINIPATH_RHF_H_ICRCERR) | ||
| 757 | strlcat(msg, "icrcerr ", len); | ||
| 758 | if (err & INFINIPATH_RHF_H_VCRCERR) | ||
| 759 | strlcat(msg, "vcrcerr ", len); | ||
| 760 | if (err & INFINIPATH_RHF_H_PARITYERR) | ||
| 761 | strlcat(msg, "parityerr ", len); | ||
| 762 | if (err & INFINIPATH_RHF_H_LENERR) | ||
| 763 | strlcat(msg, "lenerr ", len); | ||
| 764 | if (err & INFINIPATH_RHF_H_MTUERR) | ||
| 765 | strlcat(msg, "mtuerr ", len); | ||
| 766 | if (err & INFINIPATH_RHF_H_IHDRERR) | ||
| 767 | /* infinipath hdr checksum error */ | ||
| 768 | strlcat(msg, "ipathhdrerr ", len); | ||
| 769 | if (err & INFINIPATH_RHF_H_TIDERR) | ||
| 770 | strlcat(msg, "tiderr ", len); | ||
| 771 | if (err & INFINIPATH_RHF_H_MKERR) | ||
| 772 | /* bad port, offset, etc. */ | ||
| 773 | strlcat(msg, "invalid ipathhdr ", len); | ||
| 774 | if (err & INFINIPATH_RHF_H_IBERR) | ||
| 775 | strlcat(msg, "iberr ", len); | ||
| 776 | if (err & INFINIPATH_RHF_L_SWA) | ||
| 777 | strlcat(msg, "swA ", len); | ||
| 778 | if (err & INFINIPATH_RHF_L_SWB) | ||
| 779 | strlcat(msg, "swB ", len); | ||
| 780 | } | ||
| 781 | |||
| 782 | /** | ||
| 783 | * ipath_get_egrbuf - get an eager buffer | ||
| 784 | * @dd: the infinipath device | ||
| 785 | * @bufnum: the eager buffer to get | ||
| 786 | * @err: unused | ||
| 787 | * | ||
| 788 | * must only be called if ipath_pd[port] is known to be allocated | ||
| 789 | */ | ||
| 790 | static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum, | ||
| 791 | int err) | ||
| 792 | { | ||
| 793 | return dd->ipath_port0_skbs ? | ||
| 794 | (void *)dd->ipath_port0_skbs[bufnum]->data : NULL; | ||
| 795 | } | ||
| 796 | |||
| 797 | /** | ||
| 798 | * ipath_alloc_skb - allocate an skb and buffer with possible constraints | ||
| 799 | * @dd: the infinipath device | ||
| 800 | * @gfp_mask: the sk_buff SFP mask | ||
| 801 | */ | ||
| 802 | struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd, | ||
| 803 | gfp_t gfp_mask) | ||
| 804 | { | ||
| 805 | struct sk_buff *skb; | ||
| 806 | u32 len; | ||
| 807 | |||
| 808 | /* | ||
| 809 | * Only fully supported way to handle this is to allocate lots | ||
| 810 | * extra, align as needed, and then do skb_reserve(). That wastes | ||
| 811 | * a lot of memory... I'll have to hack this into infinipath_copy | ||
| 812 | * also. | ||
| 813 | */ | ||
| 814 | |||
| 815 | /* | ||
| 816 | * We need 4 extra bytes for unaligned transfer copying | ||
| 817 | */ | ||
| 818 | if (dd->ipath_flags & IPATH_4BYTE_TID) { | ||
| 819 | /* we need a 4KB multiple alignment, and there is no way | ||
| 820 | * to do it except to allocate extra and then skb_reserve | ||
| 821 | * enough to bring it up to the right alignment. | ||
| 822 | */ | ||
| 823 | len = dd->ipath_ibmaxlen + 4 + (1 << 11) - 1; | ||
| 824 | } | ||
| 825 | else | ||
| 826 | len = dd->ipath_ibmaxlen + 4; | ||
| 827 | skb = __dev_alloc_skb(len, gfp_mask); | ||
| 828 | if (!skb) { | ||
| 829 | ipath_dev_err(dd, "Failed to allocate skbuff, length %u\n", | ||
| 830 | len); | ||
| 831 | goto bail; | ||
| 832 | } | ||
| 833 | if (dd->ipath_flags & IPATH_4BYTE_TID) { | ||
| 834 | u32 una = ((1 << 11) - 1) & (unsigned long)(skb->data + 4); | ||
| 835 | if (una) | ||
| 836 | skb_reserve(skb, 4 + (1 << 11) - una); | ||
| 837 | else | ||
| 838 | skb_reserve(skb, 4); | ||
| 839 | } else | ||
| 840 | skb_reserve(skb, 4); | ||
| 841 | |||
| 842 | bail: | ||
| 843 | return skb; | ||
| 844 | } | ||
| 845 | |||
| 846 | /** | ||
| 847 | * ipath_rcv_layer - receive a packet for the layered (ethernet) driver | ||
| 848 | * @dd: the infinipath device | ||
| 849 | * @etail: the sk_buff number | ||
| 850 | * @tlen: the total packet length | ||
| 851 | * @hdr: the ethernet header | ||
| 852 | * | ||
| 853 | * Separate routine for better overall optimization | ||
| 854 | */ | ||
| 855 | static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail, | ||
| 856 | u32 tlen, struct ether_header *hdr) | ||
| 857 | { | ||
| 858 | u32 elen; | ||
| 859 | u8 pad, *bthbytes; | ||
| 860 | struct sk_buff *skb, *nskb; | ||
| 861 | |||
| 862 | if (dd->ipath_port0_skbs && hdr->sub_opcode == OPCODE_ENCAP) { | ||
| 863 | /* | ||
| 864 | * Allocate a new sk_buff to replace the one we give | ||
| 865 | * to the network stack. | ||
| 866 | */ | ||
| 867 | nskb = ipath_alloc_skb(dd, GFP_ATOMIC); | ||
| 868 | if (!nskb) { | ||
| 869 | /* count OK packets that we drop */ | ||
| 870 | ipath_stats.sps_krdrops++; | ||
| 871 | return; | ||
| 872 | } | ||
| 873 | |||
| 874 | bthbytes = (u8 *) hdr->bth; | ||
| 875 | pad = (bthbytes[1] >> 4) & 3; | ||
| 876 | /* +CRC32 */ | ||
| 877 | elen = tlen - (sizeof(*hdr) + pad + sizeof(u32)); | ||
| 878 | |||
| 879 | skb = dd->ipath_port0_skbs[etail]; | ||
| 880 | dd->ipath_port0_skbs[etail] = nskb; | ||
| 881 | skb_put(skb, elen); | ||
| 882 | |||
| 883 | dd->ipath_f_put_tid(dd, etail + (u64 __iomem *) | ||
| 884 | ((char __iomem *) dd->ipath_kregbase | ||
| 885 | + dd->ipath_rcvegrbase), 0, | ||
| 886 | virt_to_phys(nskb->data)); | ||
| 887 | |||
| 888 | __ipath_layer_rcv(dd, hdr, skb); | ||
| 889 | |||
| 890 | /* another ether packet received */ | ||
| 891 | ipath_stats.sps_ether_rpkts++; | ||
| 892 | } | ||
| 893 | else if (hdr->sub_opcode == OPCODE_LID_ARP) | ||
| 894 | __ipath_layer_rcv_lid(dd, hdr); | ||
| 895 | } | ||
| 896 | |||
| 897 | /* | ||
| 898 | * ipath_kreceive - receive a packet | ||
| 899 | * @dd: the infinipath device | ||
| 900 | * | ||
| 901 | * called from interrupt handler for errors or receive interrupt | ||
| 902 | */ | ||
| 903 | void ipath_kreceive(struct ipath_devdata *dd) | ||
| 904 | { | ||
| 905 | u64 *rc; | ||
| 906 | void *ebuf; | ||
| 907 | const u32 rsize = dd->ipath_rcvhdrentsize; /* words */ | ||
| 908 | const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ | ||
| 909 | u32 etail = -1, l, hdrqtail; | ||
| 910 | struct ips_message_header *hdr; | ||
| 911 | u32 eflags, i, etype, tlen, pkttot = 0; | ||
| 912 | static u64 totcalls; /* stats, may eventually remove */ | ||
| 913 | char emsg[128]; | ||
| 914 | |||
| 915 | if (!dd->ipath_hdrqtailptr) { | ||
| 916 | ipath_dev_err(dd, | ||
| 917 | "hdrqtailptr not set, can't do receives\n"); | ||
| 918 | goto bail; | ||
| 919 | } | ||
| 920 | |||
| 921 | /* There is already a thread processing this queue. */ | ||
| 922 | if (test_and_set_bit(0, &dd->ipath_rcv_pending)) | ||
| 923 | goto bail; | ||
| 924 | |||
| 925 | if (dd->ipath_port0head == | ||
| 926 | (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) | ||
| 927 | goto done; | ||
| 928 | |||
| 929 | gotmore: | ||
| 930 | /* | ||
| 931 | * read only once at start. If in flood situation, this helps | ||
| 932 | * performance slightly. If more arrive while we are processing, | ||
| 933 | * we'll come back here and do them | ||
| 934 | */ | ||
| 935 | hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); | ||
| 936 | |||
| 937 | for (i = 0, l = dd->ipath_port0head; l != hdrqtail; i++) { | ||
| 938 | u32 qp; | ||
| 939 | u8 *bthbytes; | ||
| 940 | |||
| 941 | rc = (u64 *) (dd->ipath_pd[0]->port_rcvhdrq + (l << 2)); | ||
| 942 | hdr = (struct ips_message_header *)&rc[1]; | ||
| 943 | /* | ||
| 944 | * could make a network order version of IPATH_KD_QP, and | ||
| 945 | * do the obvious shift before masking to speed this up. | ||
| 946 | */ | ||
| 947 | qp = ntohl(hdr->bth[1]) & 0xffffff; | ||
| 948 | bthbytes = (u8 *) hdr->bth; | ||
| 949 | |||
| 950 | eflags = ips_get_hdr_err_flags((__le32 *) rc); | ||
| 951 | etype = ips_get_rcv_type((__le32 *) rc); | ||
| 952 | /* total length */ | ||
| 953 | tlen = ips_get_length_in_bytes((__le32 *) rc); | ||
| 954 | ebuf = NULL; | ||
| 955 | if (etype != RCVHQ_RCV_TYPE_EXPECTED) { | ||
| 956 | /* | ||
| 957 | * it turns out that the chips uses an eager buffer | ||
| 958 | * for all non-expected packets, whether it "needs" | ||
| 959 | * one or not. So always get the index, but don't | ||
| 960 | * set ebuf (so we try to copy data) unless the | ||
| 961 | * length requires it. | ||
| 962 | */ | ||
| 963 | etail = ips_get_index((__le32 *) rc); | ||
| 964 | if (tlen > sizeof(*hdr) || | ||
| 965 | etype == RCVHQ_RCV_TYPE_NON_KD) | ||
| 966 | ebuf = ipath_get_egrbuf(dd, etail, 0); | ||
| 967 | } | ||
| 968 | |||
| 969 | /* | ||
| 970 | * both tiderr and ipathhdrerr are set for all plain IB | ||
| 971 | * packets; only ipathhdrerr should be set. | ||
| 972 | */ | ||
| 973 | |||
| 974 | if (etype != RCVHQ_RCV_TYPE_NON_KD && etype != | ||
| 975 | RCVHQ_RCV_TYPE_ERROR && ips_get_ipath_ver( | ||
| 976 | hdr->iph.ver_port_tid_offset) != | ||
| 977 | IPS_PROTO_VERSION) { | ||
| 978 | ipath_cdbg(PKT, "Bad InfiniPath protocol version " | ||
| 979 | "%x\n", etype); | ||
| 980 | } | ||
| 981 | |||
| 982 | if (eflags & ~(INFINIPATH_RHF_H_TIDERR | | ||
| 983 | INFINIPATH_RHF_H_IHDRERR)) { | ||
| 984 | get_rhf_errstring(eflags, emsg, sizeof emsg); | ||
| 985 | ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u " | ||
| 986 | "tlen=%x opcode=%x egridx=%x: %s\n", | ||
| 987 | eflags, l, etype, tlen, bthbytes[0], | ||
| 988 | ips_get_index((__le32 *) rc), emsg); | ||
| 989 | } else if (etype == RCVHQ_RCV_TYPE_NON_KD) { | ||
| 990 | int ret = __ipath_verbs_rcv(dd, rc + 1, | ||
| 991 | ebuf, tlen); | ||
| 992 | if (ret == -ENODEV) | ||
| 993 | ipath_cdbg(VERBOSE, | ||
| 994 | "received IB packet, " | ||
| 995 | "not SMA (QP=%x)\n", qp); | ||
| 996 | } else if (etype == RCVHQ_RCV_TYPE_EAGER) { | ||
| 997 | if (qp == IPATH_KD_QP && | ||
| 998 | bthbytes[0] == ipath_layer_rcv_opcode && | ||
| 999 | ebuf) | ||
| 1000 | ipath_rcv_layer(dd, etail, tlen, | ||
| 1001 | (struct ether_header *)hdr); | ||
| 1002 | else | ||
| 1003 | ipath_cdbg(PKT, "typ %x, opcode %x (eager, " | ||
| 1004 | "qp=%x), len %x; ignored\n", | ||
| 1005 | etype, bthbytes[0], qp, tlen); | ||
| 1006 | } | ||
| 1007 | else if (etype == RCVHQ_RCV_TYPE_EXPECTED) | ||
| 1008 | ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", | ||
| 1009 | be32_to_cpu(hdr->bth[0]) & 0xff); | ||
| 1010 | else if (eflags & (INFINIPATH_RHF_H_TIDERR | | ||
| 1011 | INFINIPATH_RHF_H_IHDRERR)) { | ||
| 1012 | /* | ||
| 1013 | * This is a type 3 packet, only the LRH is in the | ||
| 1014 | * rcvhdrq, the rest of the header is in the eager | ||
| 1015 | * buffer. | ||
| 1016 | */ | ||
| 1017 | u8 opcode; | ||
| 1018 | if (ebuf) { | ||
| 1019 | bthbytes = (u8 *) ebuf; | ||
| 1020 | opcode = *bthbytes; | ||
| 1021 | } | ||
| 1022 | else | ||
| 1023 | opcode = 0; | ||
| 1024 | get_rhf_errstring(eflags, emsg, sizeof emsg); | ||
| 1025 | ipath_dbg("Err %x (%s), opcode %x, egrbuf %x, " | ||
| 1026 | "len %x\n", eflags, emsg, opcode, etail, | ||
| 1027 | tlen); | ||
| 1028 | } else { | ||
| 1029 | /* | ||
| 1030 | * error packet, type of error unknown. | ||
| 1031 | * Probably type 3, but we don't know, so don't | ||
| 1032 | * even try to print the opcode, etc. | ||
| 1033 | */ | ||
| 1034 | ipath_dbg("Error Pkt, but no eflags! egrbuf %x, " | ||
| 1035 | "len %x\nhdrq@%lx;hdrq+%x rhf: %llx; " | ||
| 1036 | "hdr %llx %llx %llx %llx %llx\n", | ||
| 1037 | etail, tlen, (unsigned long) rc, l, | ||
| 1038 | (unsigned long long) rc[0], | ||
| 1039 | (unsigned long long) rc[1], | ||
| 1040 | (unsigned long long) rc[2], | ||
| 1041 | (unsigned long long) rc[3], | ||
| 1042 | (unsigned long long) rc[4], | ||
| 1043 | (unsigned long long) rc[5]); | ||
| 1044 | } | ||
| 1045 | l += rsize; | ||
| 1046 | if (l >= maxcnt) | ||
| 1047 | l = 0; | ||
| 1048 | /* | ||
| 1049 | * update for each packet, to help prevent overflows if we | ||
| 1050 | * have lots of packets. | ||
| 1051 | */ | ||
| 1052 | (void)ipath_write_ureg(dd, ur_rcvhdrhead, | ||
| 1053 | dd->ipath_rhdrhead_intr_off | l, 0); | ||
| 1054 | if (etype != RCVHQ_RCV_TYPE_EXPECTED) | ||
| 1055 | (void)ipath_write_ureg(dd, ur_rcvegrindexhead, | ||
| 1056 | etail, 0); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | pkttot += i; | ||
| 1060 | |||
| 1061 | dd->ipath_port0head = l; | ||
| 1062 | |||
| 1063 | if (hdrqtail != (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) | ||
| 1064 | /* more arrived while we handled first batch */ | ||
| 1065 | goto gotmore; | ||
| 1066 | |||
| 1067 | if (pkttot > ipath_stats.sps_maxpkts_call) | ||
| 1068 | ipath_stats.sps_maxpkts_call = pkttot; | ||
| 1069 | ipath_stats.sps_port0pkts += pkttot; | ||
| 1070 | ipath_stats.sps_avgpkts_call = | ||
| 1071 | ipath_stats.sps_port0pkts / ++totcalls; | ||
| 1072 | |||
| 1073 | done: | ||
| 1074 | clear_bit(0, &dd->ipath_rcv_pending); | ||
| 1075 | smp_mb__after_clear_bit(); | ||
| 1076 | |||
| 1077 | bail:; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | /** | ||
| 1081 | * ipath_update_pio_bufs - update shadow copy of the PIO availability map | ||
| 1082 | * @dd: the infinipath device | ||
| 1083 | * | ||
| 1084 | * called whenever our local copy indicates we have run out of send buffers | ||
| 1085 | * NOTE: This can be called from interrupt context by some code | ||
| 1086 | * and from non-interrupt context by ipath_getpiobuf(). | ||
| 1087 | */ | ||
| 1088 | |||
| 1089 | static void ipath_update_pio_bufs(struct ipath_devdata *dd) | ||
| 1090 | { | ||
| 1091 | unsigned long flags; | ||
| 1092 | int i; | ||
| 1093 | const unsigned piobregs = (unsigned)dd->ipath_pioavregs; | ||
| 1094 | |||
| 1095 | /* If the generation (check) bits have changed, then we update the | ||
| 1096 | * busy bit for the corresponding PIO buffer. This algorithm will | ||
| 1097 | * modify positions to the value they already have in some cases | ||
| 1098 | * (i.e., no change), but it's faster than changing only the bits | ||
| 1099 | * that have changed. | ||
| 1100 | * | ||
| 1101 | * We would like to do this atomicly, to avoid spinlocks in the | ||
| 1102 | * critical send path, but that's not really possible, given the | ||
| 1103 | * type of changes, and that this routine could be called on | ||
| 1104 | * multiple cpu's simultaneously, so we lock in this routine only, | ||
| 1105 | * to avoid conflicting updates; all we change is the shadow, and | ||
| 1106 | * it's a single 64 bit memory location, so by definition the update | ||
| 1107 | * is atomic in terms of what other cpu's can see in testing the | ||
| 1108 | * bits. The spin_lock overhead isn't too bad, since it only | ||
| 1109 | * happens when all buffers are in use, so only cpu overhead, not | ||
| 1110 | * latency or bandwidth is affected. | ||
| 1111 | */ | ||
| 1112 | #define _IPATH_ALL_CHECKBITS 0x5555555555555555ULL | ||
| 1113 | if (!dd->ipath_pioavailregs_dma) { | ||
| 1114 | ipath_dbg("Update shadow pioavail, but regs_dma NULL!\n"); | ||
| 1115 | return; | ||
| 1116 | } | ||
| 1117 | if (ipath_debug & __IPATH_VERBDBG) { | ||
| 1118 | /* only if packet debug and verbose */ | ||
| 1119 | volatile __le64 *dma = dd->ipath_pioavailregs_dma; | ||
| 1120 | unsigned long *shadow = dd->ipath_pioavailshadow; | ||
| 1121 | |||
| 1122 | ipath_cdbg(PKT, "Refill avail, dma0=%llx shad0=%lx, " | ||
| 1123 | "d1=%llx s1=%lx, d2=%llx s2=%lx, d3=%llx " | ||
| 1124 | "s3=%lx\n", | ||
| 1125 | (unsigned long long) le64_to_cpu(dma[0]), | ||
| 1126 | shadow[0], | ||
| 1127 | (unsigned long long) le64_to_cpu(dma[1]), | ||
| 1128 | shadow[1], | ||
| 1129 | (unsigned long long) le64_to_cpu(dma[2]), | ||
| 1130 | shadow[2], | ||
| 1131 | (unsigned long long) le64_to_cpu(dma[3]), | ||
| 1132 | shadow[3]); | ||
| 1133 | if (piobregs > 4) | ||
| 1134 | ipath_cdbg( | ||
| 1135 | PKT, "2nd group, dma4=%llx shad4=%lx, " | ||
| 1136 | "d5=%llx s5=%lx, d6=%llx s6=%lx, " | ||
| 1137 | "d7=%llx s7=%lx\n", | ||
| 1138 | (unsigned long long) le64_to_cpu(dma[4]), | ||
| 1139 | shadow[4], | ||
| 1140 | (unsigned long long) le64_to_cpu(dma[5]), | ||
| 1141 | shadow[5], | ||
| 1142 | (unsigned long long) le64_to_cpu(dma[6]), | ||
| 1143 | shadow[6], | ||
| 1144 | (unsigned long long) le64_to_cpu(dma[7]), | ||
| 1145 | shadow[7]); | ||
| 1146 | } | ||
| 1147 | spin_lock_irqsave(&ipath_pioavail_lock, flags); | ||
| 1148 | for (i = 0; i < piobregs; i++) { | ||
| 1149 | u64 pchbusy, pchg, piov, pnew; | ||
| 1150 | /* | ||
| 1151 | * Chip Errata: bug 6641; even and odd qwords>3 are swapped | ||
| 1152 | */ | ||
| 1153 | if (i > 3) { | ||
| 1154 | if (i & 1) | ||
| 1155 | piov = le64_to_cpu( | ||
| 1156 | dd->ipath_pioavailregs_dma[i - 1]); | ||
| 1157 | else | ||
| 1158 | piov = le64_to_cpu( | ||
| 1159 | dd->ipath_pioavailregs_dma[i + 1]); | ||
| 1160 | } else | ||
| 1161 | piov = le64_to_cpu(dd->ipath_pioavailregs_dma[i]); | ||
| 1162 | pchg = _IPATH_ALL_CHECKBITS & | ||
| 1163 | ~(dd->ipath_pioavailshadow[i] ^ piov); | ||
| 1164 | pchbusy = pchg << INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT; | ||
| 1165 | if (pchg && (pchbusy & dd->ipath_pioavailshadow[i])) { | ||
| 1166 | pnew = dd->ipath_pioavailshadow[i] & ~pchbusy; | ||
| 1167 | pnew |= piov & pchbusy; | ||
| 1168 | dd->ipath_pioavailshadow[i] = pnew; | ||
| 1169 | } | ||
| 1170 | } | ||
| 1171 | spin_unlock_irqrestore(&ipath_pioavail_lock, flags); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | /** | ||
| 1175 | * ipath_setrcvhdrsize - set the receive header size | ||
| 1176 | * @dd: the infinipath device | ||
| 1177 | * @rhdrsize: the receive header size | ||
| 1178 | * | ||
| 1179 | * called from user init code, and also layered driver init | ||
| 1180 | */ | ||
| 1181 | int ipath_setrcvhdrsize(struct ipath_devdata *dd, unsigned rhdrsize) | ||
| 1182 | { | ||
| 1183 | int ret = 0; | ||
| 1184 | |||
| 1185 | if (dd->ipath_flags & IPATH_RCVHDRSZ_SET) { | ||
| 1186 | if (dd->ipath_rcvhdrsize != rhdrsize) { | ||
| 1187 | dev_info(&dd->pcidev->dev, | ||
| 1188 | "Error: can't set protocol header " | ||
| 1189 | "size %u, already %u\n", | ||
| 1190 | rhdrsize, dd->ipath_rcvhdrsize); | ||
| 1191 | ret = -EAGAIN; | ||
| 1192 | } else | ||
| 1193 | ipath_cdbg(VERBOSE, "Reuse same protocol header " | ||
| 1194 | "size %u\n", dd->ipath_rcvhdrsize); | ||
| 1195 | } else if (rhdrsize > (dd->ipath_rcvhdrentsize - | ||
| 1196 | (sizeof(u64) / sizeof(u32)))) { | ||
| 1197 | ipath_dbg("Error: can't set protocol header size %u " | ||
| 1198 | "(> max %u)\n", rhdrsize, | ||
| 1199 | dd->ipath_rcvhdrentsize - | ||
| 1200 | (u32) (sizeof(u64) / sizeof(u32))); | ||
| 1201 | ret = -EOVERFLOW; | ||
| 1202 | } else { | ||
| 1203 | dd->ipath_flags |= IPATH_RCVHDRSZ_SET; | ||
| 1204 | dd->ipath_rcvhdrsize = rhdrsize; | ||
| 1205 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrsize, | ||
| 1206 | dd->ipath_rcvhdrsize); | ||
| 1207 | ipath_cdbg(VERBOSE, "Set protocol header size to %u\n", | ||
| 1208 | dd->ipath_rcvhdrsize); | ||
| 1209 | } | ||
| 1210 | return ret; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | /** | ||
| 1214 | * ipath_getpiobuf - find an available pio buffer | ||
| 1215 | * @dd: the infinipath device | ||
| 1216 | * @pbufnum: the buffer number is placed here | ||
| 1217 | * | ||
| 1218 | * do appropriate marking as busy, etc. | ||
| 1219 | * returns buffer number if one found (>=0), negative number is error. | ||
| 1220 | * Used by ipath_sma_send_pkt and ipath_layer_send | ||
| 1221 | */ | ||
| 1222 | u32 __iomem *ipath_getpiobuf(struct ipath_devdata *dd, u32 * pbufnum) | ||
| 1223 | { | ||
| 1224 | int i, j, starti, updated = 0; | ||
| 1225 | unsigned piobcnt, iter; | ||
| 1226 | unsigned long flags; | ||
| 1227 | unsigned long *shadow = dd->ipath_pioavailshadow; | ||
| 1228 | u32 __iomem *buf; | ||
| 1229 | |||
| 1230 | piobcnt = (unsigned)(dd->ipath_piobcnt2k | ||
| 1231 | + dd->ipath_piobcnt4k); | ||
| 1232 | starti = dd->ipath_lastport_piobuf; | ||
| 1233 | iter = piobcnt - starti; | ||
| 1234 | if (dd->ipath_upd_pio_shadow) { | ||
| 1235 | /* | ||
| 1236 | * Minor optimization. If we had no buffers on last call, | ||
| 1237 | * start out by doing the update; continue and do scan even | ||
| 1238 | * if no buffers were updated, to be paranoid | ||
| 1239 | */ | ||
| 1240 | ipath_update_pio_bufs(dd); | ||
| 1241 | /* we scanned here, don't do it at end of scan */ | ||
| 1242 | updated = 1; | ||
| 1243 | i = starti; | ||
| 1244 | } else | ||
| 1245 | i = dd->ipath_lastpioindex; | ||
| 1246 | |||
| 1247 | rescan: | ||
| 1248 | /* | ||
| 1249 | * while test_and_set_bit() is atomic, we do that and then the | ||
| 1250 | * change_bit(), and the pair is not. See if this is the cause | ||
| 1251 | * of the remaining armlaunch errors. | ||
| 1252 | */ | ||
| 1253 | spin_lock_irqsave(&ipath_pioavail_lock, flags); | ||
| 1254 | for (j = 0; j < iter; j++, i++) { | ||
| 1255 | if (i >= piobcnt) | ||
| 1256 | i = starti; | ||
| 1257 | /* | ||
| 1258 | * To avoid bus lock overhead, we first find a candidate | ||
| 1259 | * buffer, then do the test and set, and continue if that | ||
| 1260 | * fails. | ||
| 1261 | */ | ||
| 1262 | if (test_bit((2 * i) + 1, shadow) || | ||
| 1263 | test_and_set_bit((2 * i) + 1, shadow)) | ||
| 1264 | continue; | ||
| 1265 | /* flip generation bit */ | ||
| 1266 | change_bit(2 * i, shadow); | ||
| 1267 | break; | ||
| 1268 | } | ||
| 1269 | spin_unlock_irqrestore(&ipath_pioavail_lock, flags); | ||
| 1270 | |||
| 1271 | if (j == iter) { | ||
| 1272 | volatile __le64 *dma = dd->ipath_pioavailregs_dma; | ||
| 1273 | |||
| 1274 | /* | ||
| 1275 | * first time through; shadow exhausted, but may be real | ||
| 1276 | * buffers available, so go see; if any updated, rescan | ||
| 1277 | * (once) | ||
| 1278 | */ | ||
| 1279 | if (!updated) { | ||
| 1280 | ipath_update_pio_bufs(dd); | ||
| 1281 | updated = 1; | ||
| 1282 | i = starti; | ||
| 1283 | goto rescan; | ||
| 1284 | } | ||
| 1285 | dd->ipath_upd_pio_shadow = 1; | ||
| 1286 | /* | ||
| 1287 | * not atomic, but if we lose one once in a while, that's OK | ||
| 1288 | */ | ||
| 1289 | ipath_stats.sps_nopiobufs++; | ||
| 1290 | if (!(++dd->ipath_consec_nopiobuf % 100000)) { | ||
| 1291 | ipath_dbg( | ||
| 1292 | "%u pio sends with no bufavail; dmacopy: " | ||
| 1293 | "%llx %llx %llx %llx; shadow: " | ||
| 1294 | "%lx %lx %lx %lx\n", | ||
| 1295 | dd->ipath_consec_nopiobuf, | ||
| 1296 | (unsigned long long) le64_to_cpu(dma[0]), | ||
| 1297 | (unsigned long long) le64_to_cpu(dma[1]), | ||
| 1298 | (unsigned long long) le64_to_cpu(dma[2]), | ||
| 1299 | (unsigned long long) le64_to_cpu(dma[3]), | ||
| 1300 | shadow[0], shadow[1], shadow[2], | ||
| 1301 | shadow[3]); | ||
| 1302 | /* | ||
| 1303 | * 4 buffers per byte, 4 registers above, cover rest | ||
| 1304 | * below | ||
| 1305 | */ | ||
| 1306 | if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > | ||
| 1307 | (sizeof(shadow[0]) * 4 * 4)) | ||
| 1308 | ipath_dbg("2nd group: dmacopy: %llx %llx " | ||
| 1309 | "%llx %llx; shadow: %lx %lx " | ||
| 1310 | "%lx %lx\n", | ||
| 1311 | (unsigned long long) | ||
| 1312 | le64_to_cpu(dma[4]), | ||
| 1313 | (unsigned long long) | ||
| 1314 | le64_to_cpu(dma[5]), | ||
| 1315 | (unsigned long long) | ||
| 1316 | le64_to_cpu(dma[6]), | ||
| 1317 | (unsigned long long) | ||
| 1318 | le64_to_cpu(dma[7]), | ||
| 1319 | shadow[4], shadow[5], | ||
| 1320 | shadow[6], shadow[7]); | ||
| 1321 | } | ||
| 1322 | buf = NULL; | ||
| 1323 | goto bail; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | if (updated) | ||
| 1327 | /* | ||
| 1328 | * ran out of bufs, now some (at least this one we just | ||
| 1329 | * got) are now available, so tell the layered driver. | ||
| 1330 | */ | ||
| 1331 | __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE); | ||
| 1332 | |||
| 1333 | /* | ||
| 1334 | * set next starting place. Since it's just an optimization, | ||
| 1335 | * it doesn't matter who wins on this, so no locking | ||
| 1336 | */ | ||
| 1337 | dd->ipath_lastpioindex = i + 1; | ||
| 1338 | if (dd->ipath_upd_pio_shadow) | ||
| 1339 | dd->ipath_upd_pio_shadow = 0; | ||
| 1340 | if (dd->ipath_consec_nopiobuf) | ||
| 1341 | dd->ipath_consec_nopiobuf = 0; | ||
| 1342 | if (i < dd->ipath_piobcnt2k) | ||
| 1343 | buf = (u32 __iomem *) (dd->ipath_pio2kbase + | ||
| 1344 | i * dd->ipath_palign); | ||
| 1345 | else | ||
| 1346 | buf = (u32 __iomem *) | ||
| 1347 | (dd->ipath_pio4kbase + | ||
| 1348 | (i - dd->ipath_piobcnt2k) * dd->ipath_4kalign); | ||
| 1349 | ipath_cdbg(VERBOSE, "Return piobuf%u %uk @ %p\n", | ||
| 1350 | i, (i < dd->ipath_piobcnt2k) ? 2 : 4, buf); | ||
| 1351 | if (pbufnum) | ||
| 1352 | *pbufnum = i; | ||
| 1353 | |||
| 1354 | bail: | ||
| 1355 | return buf; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | /** | ||
| 1359 | * ipath_create_rcvhdrq - create a receive header queue | ||
| 1360 | * @dd: the infinipath device | ||
| 1361 | * @pd: the port data | ||
| 1362 | * | ||
| 1363 | * this *must* be physically contiguous memory, and for now, | ||
| 1364 | * that limits it to what kmalloc can do. | ||
| 1365 | */ | ||
| 1366 | int ipath_create_rcvhdrq(struct ipath_devdata *dd, | ||
| 1367 | struct ipath_portdata *pd) | ||
| 1368 | { | ||
| 1369 | int ret = 0, amt; | ||
| 1370 | |||
| 1371 | amt = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize * | ||
| 1372 | sizeof(u32), PAGE_SIZE); | ||
| 1373 | if (!pd->port_rcvhdrq) { | ||
| 1374 | /* | ||
| 1375 | * not using REPEAT isn't viable; at 128KB, we can easily | ||
| 1376 | * fail this. The problem with REPEAT is we can block here | ||
| 1377 | * "forever". There isn't an inbetween, unfortunately. We | ||
| 1378 | * could reduce the risk by never freeing the rcvhdrq except | ||
| 1379 | * at unload, but even then, the first time a port is used, | ||
| 1380 | * we could delay for some time... | ||
| 1381 | */ | ||
| 1382 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; | ||
| 1383 | |||
| 1384 | pd->port_rcvhdrq = dma_alloc_coherent( | ||
| 1385 | &dd->pcidev->dev, amt, &pd->port_rcvhdrq_phys, | ||
| 1386 | gfp_flags); | ||
| 1387 | |||
| 1388 | if (!pd->port_rcvhdrq) { | ||
| 1389 | ipath_dev_err(dd, "attempt to allocate %d bytes " | ||
| 1390 | "for port %u rcvhdrq failed\n", | ||
| 1391 | amt, pd->port_port); | ||
| 1392 | ret = -ENOMEM; | ||
| 1393 | goto bail; | ||
| 1394 | } | ||
| 1395 | |||
| 1396 | pd->port_rcvhdrq_size = amt; | ||
| 1397 | |||
| 1398 | ipath_cdbg(VERBOSE, "%d pages at %p (phys %lx) size=%lu " | ||
| 1399 | "for port %u rcvhdr Q\n", | ||
| 1400 | amt >> PAGE_SHIFT, pd->port_rcvhdrq, | ||
| 1401 | (unsigned long) pd->port_rcvhdrq_phys, | ||
| 1402 | (unsigned long) pd->port_rcvhdrq_size, | ||
| 1403 | pd->port_port); | ||
| 1404 | } else { | ||
| 1405 | /* | ||
| 1406 | * clear for security, sanity, and/or debugging, each | ||
| 1407 | * time we reuse | ||
| 1408 | */ | ||
| 1409 | memset(pd->port_rcvhdrq, 0, amt); | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | /* | ||
| 1413 | * tell chip each time we init it, even if we are re-using previous | ||
| 1414 | * memory (we zero it at process close) | ||
| 1415 | */ | ||
| 1416 | ipath_cdbg(VERBOSE, "writing port %d rcvhdraddr as %lx\n", | ||
| 1417 | pd->port_port, (unsigned long) pd->port_rcvhdrq_phys); | ||
| 1418 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, | ||
| 1419 | pd->port_port, pd->port_rcvhdrq_phys); | ||
| 1420 | |||
| 1421 | ret = 0; | ||
| 1422 | bail: | ||
| 1423 | return ret; | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | int ipath_waitfor_complete(struct ipath_devdata *dd, ipath_kreg reg_id, | ||
| 1427 | u64 bits_to_wait_for, u64 * valp) | ||
| 1428 | { | ||
| 1429 | unsigned long timeout; | ||
| 1430 | u64 lastval, val; | ||
| 1431 | int ret; | ||
| 1432 | |||
| 1433 | lastval = ipath_read_kreg64(dd, reg_id); | ||
| 1434 | /* wait a ridiculously long time */ | ||
| 1435 | timeout = jiffies + msecs_to_jiffies(5); | ||
| 1436 | do { | ||
| 1437 | val = ipath_read_kreg64(dd, reg_id); | ||
| 1438 | /* set so they have something, even on failures. */ | ||
| 1439 | *valp = val; | ||
| 1440 | if ((val & bits_to_wait_for) == bits_to_wait_for) { | ||
| 1441 | ret = 0; | ||
| 1442 | break; | ||
| 1443 | } | ||
| 1444 | if (val != lastval) | ||
| 1445 | ipath_cdbg(VERBOSE, "Changed from %llx to %llx, " | ||
| 1446 | "waiting for %llx bits\n", | ||
| 1447 | (unsigned long long) lastval, | ||
| 1448 | (unsigned long long) val, | ||
| 1449 | (unsigned long long) bits_to_wait_for); | ||
| 1450 | cond_resched(); | ||
| 1451 | if (time_after(jiffies, timeout)) { | ||
| 1452 | ipath_dbg("Didn't get bits %llx in register 0x%x, " | ||
| 1453 | "got %llx\n", | ||
| 1454 | (unsigned long long) bits_to_wait_for, | ||
| 1455 | reg_id, (unsigned long long) *valp); | ||
| 1456 | ret = -ENODEV; | ||
| 1457 | break; | ||
| 1458 | } | ||
| 1459 | } while (1); | ||
| 1460 | |||
| 1461 | return ret; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | /** | ||
| 1465 | * ipath_waitfor_mdio_cmdready - wait for last command to complete | ||
| 1466 | * @dd: the infinipath device | ||
| 1467 | * | ||
| 1468 | * Like ipath_waitfor_complete(), but we wait for the CMDVALID bit to go | ||
| 1469 | * away indicating the last command has completed. It doesn't return data | ||
| 1470 | */ | ||
| 1471 | int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd) | ||
| 1472 | { | ||
| 1473 | unsigned long timeout; | ||
| 1474 | u64 val; | ||
| 1475 | int ret; | ||
| 1476 | |||
| 1477 | /* wait a ridiculously long time */ | ||
| 1478 | timeout = jiffies + msecs_to_jiffies(5); | ||
| 1479 | do { | ||
| 1480 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_mdio); | ||
| 1481 | if (!(val & IPATH_MDIO_CMDVALID)) { | ||
| 1482 | ret = 0; | ||
| 1483 | break; | ||
| 1484 | } | ||
| 1485 | cond_resched(); | ||
| 1486 | if (time_after(jiffies, timeout)) { | ||
| 1487 | ipath_dbg("CMDVALID stuck in mdio reg? (%llx)\n", | ||
| 1488 | (unsigned long long) val); | ||
| 1489 | ret = -ENODEV; | ||
| 1490 | break; | ||
| 1491 | } | ||
| 1492 | } while (1); | ||
| 1493 | |||
| 1494 | return ret; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) | ||
| 1498 | { | ||
| 1499 | static const char *what[4] = { | ||
| 1500 | [0] = "DOWN", | ||
| 1501 | [INFINIPATH_IBCC_LINKCMD_INIT] = "INIT", | ||
| 1502 | [INFINIPATH_IBCC_LINKCMD_ARMED] = "ARMED", | ||
| 1503 | [INFINIPATH_IBCC_LINKCMD_ACTIVE] = "ACTIVE" | ||
| 1504 | }; | ||
| 1505 | ipath_cdbg(SMA, "Trying to move unit %u to %s, current ltstate " | ||
| 1506 | "is %s\n", dd->ipath_unit, | ||
| 1507 | what[(which >> INFINIPATH_IBCC_LINKCMD_SHIFT) & | ||
| 1508 | INFINIPATH_IBCC_LINKCMD_MASK], | ||
| 1509 | ipath_ibcstatus_str[ | ||
| 1510 | (ipath_read_kreg64 | ||
| 1511 | (dd, dd->ipath_kregs->kr_ibcstatus) >> | ||
| 1512 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & | ||
| 1513 | INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); | ||
| 1514 | |||
| 1515 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
| 1516 | dd->ipath_ibcctrl | which); | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | /** | ||
| 1520 | * ipath_read_kreg64_port - read a device's per-port 64-bit kernel register | ||
| 1521 | * @dd: the infinipath device | ||
| 1522 | * @regno: the register number to read | ||
| 1523 | * @port: the port containing the register | ||
| 1524 | * | ||
| 1525 | * Registers that vary with the chip implementation constants (port) | ||
| 1526 | * use this routine. | ||
| 1527 | */ | ||
| 1528 | u64 ipath_read_kreg64_port(const struct ipath_devdata *dd, ipath_kreg regno, | ||
| 1529 | unsigned port) | ||
| 1530 | { | ||
| 1531 | u16 where; | ||
| 1532 | |||
| 1533 | if (port < dd->ipath_portcnt && | ||
| 1534 | (regno == dd->ipath_kregs->kr_rcvhdraddr || | ||
| 1535 | regno == dd->ipath_kregs->kr_rcvhdrtailaddr)) | ||
| 1536 | where = regno + port; | ||
| 1537 | else | ||
| 1538 | where = -1; | ||
| 1539 | |||
| 1540 | return ipath_read_kreg64(dd, where); | ||
| 1541 | } | ||
| 1542 | |||
| 1543 | /** | ||
| 1544 | * ipath_write_kreg_port - write a device's per-port 64-bit kernel register | ||
| 1545 | * @dd: the infinipath device | ||
| 1546 | * @regno: the register number to write | ||
| 1547 | * @port: the port containing the register | ||
| 1548 | * @value: the value to write | ||
| 1549 | * | ||
| 1550 | * Registers that vary with the chip implementation constants (port) | ||
| 1551 | * use this routine. | ||
| 1552 | */ | ||
| 1553 | void ipath_write_kreg_port(const struct ipath_devdata *dd, ipath_kreg regno, | ||
| 1554 | unsigned port, u64 value) | ||
| 1555 | { | ||
| 1556 | u16 where; | ||
| 1557 | |||
| 1558 | if (port < dd->ipath_portcnt && | ||
| 1559 | (regno == dd->ipath_kregs->kr_rcvhdraddr || | ||
| 1560 | regno == dd->ipath_kregs->kr_rcvhdrtailaddr)) | ||
| 1561 | where = regno + port; | ||
| 1562 | else | ||
| 1563 | where = -1; | ||
| 1564 | |||
| 1565 | ipath_write_kreg(dd, where, value); | ||
| 1566 | } | ||
| 1567 | |||
| 1568 | /** | ||
| 1569 | * ipath_shutdown_device - shut down a device | ||
| 1570 | * @dd: the infinipath device | ||
| 1571 | * | ||
| 1572 | * This is called to make the device quiet when we are about to | ||
| 1573 | * unload the driver, and also when the device is administratively | ||
| 1574 | * disabled. It does not free any data structures. | ||
| 1575 | * Everything it does has to be setup again by ipath_init_chip(dd,1) | ||
| 1576 | */ | ||
| 1577 | void ipath_shutdown_device(struct ipath_devdata *dd) | ||
| 1578 | { | ||
| 1579 | u64 val; | ||
| 1580 | |||
| 1581 | ipath_dbg("Shutting down the device\n"); | ||
| 1582 | |||
| 1583 | dd->ipath_flags |= IPATH_LINKUNK; | ||
| 1584 | dd->ipath_flags &= ~(IPATH_INITTED | IPATH_LINKDOWN | | ||
| 1585 | IPATH_LINKINIT | IPATH_LINKARMED | | ||
| 1586 | IPATH_LINKACTIVE); | ||
| 1587 | *dd->ipath_statusp &= ~(IPATH_STATUS_IB_CONF | | ||
| 1588 | IPATH_STATUS_IB_READY); | ||
| 1589 | |||
| 1590 | /* mask interrupts, but not errors */ | ||
| 1591 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); | ||
| 1592 | |||
| 1593 | dd->ipath_rcvctrl = 0; | ||
| 1594 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 1595 | dd->ipath_rcvctrl); | ||
| 1596 | |||
| 1597 | /* | ||
| 1598 | * gracefully stop all sends allowing any in progress to trickle out | ||
| 1599 | * first. | ||
| 1600 | */ | ||
| 1601 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 0ULL); | ||
| 1602 | /* flush it */ | ||
| 1603 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 1604 | /* | ||
| 1605 | * enough for anything that's going to trickle out to have actually | ||
| 1606 | * done so. | ||
| 1607 | */ | ||
| 1608 | udelay(5); | ||
| 1609 | |||
| 1610 | /* | ||
| 1611 | * abort any armed or launched PIO buffers that didn't go. (self | ||
| 1612 | * clearing). Will cause any packet currently being transmitted to | ||
| 1613 | * go out with an EBP, and may also cause a short packet error on | ||
| 1614 | * the receiver. | ||
| 1615 | */ | ||
| 1616 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 1617 | INFINIPATH_S_ABORT); | ||
| 1618 | |||
| 1619 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << | ||
| 1620 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | ||
| 1621 | |||
| 1622 | /* | ||
| 1623 | * we are shutting down, so tell the layered driver. We don't do | ||
| 1624 | * this on just a link state change, much like ethernet, a cable | ||
| 1625 | * unplug, etc. doesn't change driver state | ||
| 1626 | */ | ||
| 1627 | ipath_layer_intr(dd, IPATH_LAYER_INT_IF_DOWN); | ||
| 1628 | |||
| 1629 | /* disable IBC */ | ||
| 1630 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; | ||
| 1631 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 1632 | dd->ipath_control); | ||
| 1633 | |||
| 1634 | /* | ||
| 1635 | * clear SerdesEnable and turn the leds off; do this here because | ||
| 1636 | * we are unloading, so don't count on interrupts to move along | ||
| 1637 | * Turn the LEDs off explictly for the same reason. | ||
| 1638 | */ | ||
| 1639 | dd->ipath_f_quiet_serdes(dd); | ||
| 1640 | dd->ipath_f_setextled(dd, 0, 0); | ||
| 1641 | |||
| 1642 | if (dd->ipath_stats_timer_active) { | ||
| 1643 | del_timer_sync(&dd->ipath_stats_timer); | ||
| 1644 | dd->ipath_stats_timer_active = 0; | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | /* | ||
| 1648 | * clear all interrupts and errors, so that the next time the driver | ||
| 1649 | * is loaded or device is enabled, we know that whatever is set | ||
| 1650 | * happened while we were unloaded | ||
| 1651 | */ | ||
| 1652 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 1653 | ~0ULL & ~INFINIPATH_HWE_MEMBISTFAILED); | ||
| 1654 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); | ||
| 1655 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | /** | ||
| 1659 | * ipath_free_pddata - free a port's allocated data | ||
| 1660 | * @dd: the infinipath device | ||
| 1661 | * @port: the port | ||
| 1662 | * @freehdrq: free the port data structure if true | ||
| 1663 | * | ||
| 1664 | * when closing, free up any allocated data for a port, if the | ||
| 1665 | * reference count goes to zero | ||
| 1666 | * Note: this also optionally frees the portdata itself! | ||
| 1667 | * Any changes here have to be matched up with the reinit case | ||
| 1668 | * of ipath_init_chip(), which calls this routine on reinit after reset. | ||
| 1669 | */ | ||
| 1670 | void ipath_free_pddata(struct ipath_devdata *dd, u32 port, int freehdrq) | ||
| 1671 | { | ||
| 1672 | struct ipath_portdata *pd = dd->ipath_pd[port]; | ||
| 1673 | |||
| 1674 | if (!pd) | ||
| 1675 | return; | ||
| 1676 | if (freehdrq) | ||
| 1677 | /* | ||
| 1678 | * only clear and free portdata if we are going to also | ||
| 1679 | * release the hdrq, otherwise we leak the hdrq on each | ||
| 1680 | * open/close cycle | ||
| 1681 | */ | ||
| 1682 | dd->ipath_pd[port] = NULL; | ||
| 1683 | if (freehdrq && pd->port_rcvhdrq) { | ||
| 1684 | ipath_cdbg(VERBOSE, "free closed port %d rcvhdrq @ %p " | ||
| 1685 | "(size=%lu)\n", pd->port_port, pd->port_rcvhdrq, | ||
| 1686 | (unsigned long) pd->port_rcvhdrq_size); | ||
| 1687 | dma_free_coherent(&dd->pcidev->dev, pd->port_rcvhdrq_size, | ||
| 1688 | pd->port_rcvhdrq, pd->port_rcvhdrq_phys); | ||
| 1689 | pd->port_rcvhdrq = NULL; | ||
| 1690 | } | ||
| 1691 | if (port && pd->port_rcvegrbuf) { | ||
| 1692 | /* always free this */ | ||
| 1693 | if (pd->port_rcvegrbuf) { | ||
| 1694 | unsigned e; | ||
| 1695 | |||
| 1696 | for (e = 0; e < pd->port_rcvegrbuf_chunks; e++) { | ||
| 1697 | void *base = pd->port_rcvegrbuf[e]; | ||
| 1698 | size_t size = pd->port_rcvegrbuf_size; | ||
| 1699 | |||
| 1700 | ipath_cdbg(VERBOSE, "egrbuf free(%p, %lu), " | ||
| 1701 | "chunk %u/%u\n", base, | ||
| 1702 | (unsigned long) size, | ||
| 1703 | e, pd->port_rcvegrbuf_chunks); | ||
| 1704 | dma_free_coherent( | ||
| 1705 | &dd->pcidev->dev, size, base, | ||
| 1706 | pd->port_rcvegrbuf_phys[e]); | ||
| 1707 | } | ||
| 1708 | vfree(pd->port_rcvegrbuf); | ||
| 1709 | pd->port_rcvegrbuf = NULL; | ||
| 1710 | vfree(pd->port_rcvegrbuf_phys); | ||
| 1711 | pd->port_rcvegrbuf_phys = NULL; | ||
| 1712 | } | ||
| 1713 | pd->port_rcvegrbuf_chunks = 0; | ||
| 1714 | } else if (port == 0 && dd->ipath_port0_skbs) { | ||
| 1715 | unsigned e; | ||
| 1716 | struct sk_buff **skbs = dd->ipath_port0_skbs; | ||
| 1717 | |||
| 1718 | dd->ipath_port0_skbs = NULL; | ||
| 1719 | ipath_cdbg(VERBOSE, "free closed port %d ipath_port0_skbs " | ||
| 1720 | "@ %p\n", pd->port_port, skbs); | ||
| 1721 | for (e = 0; e < dd->ipath_rcvegrcnt; e++) | ||
| 1722 | if (skbs[e]) | ||
| 1723 | dev_kfree_skb(skbs[e]); | ||
| 1724 | vfree(skbs); | ||
| 1725 | } | ||
| 1726 | if (freehdrq) { | ||
| 1727 | kfree(pd->port_tid_pg_list); | ||
| 1728 | kfree(pd); | ||
| 1729 | } | ||
| 1730 | } | ||
| 1731 | |||
| 1732 | int __init infinipath_init(void) | ||
| 1733 | { | ||
| 1734 | int ret; | ||
| 1735 | |||
| 1736 | ipath_dbg(KERN_INFO DRIVER_LOAD_MSG "%s", ipath_core_version); | ||
| 1737 | |||
| 1738 | /* | ||
| 1739 | * These must be called before the driver is registered with | ||
| 1740 | * the PCI subsystem. | ||
| 1741 | */ | ||
| 1742 | idr_init(&unit_table); | ||
| 1743 | if (!idr_pre_get(&unit_table, GFP_KERNEL)) { | ||
| 1744 | ret = -ENOMEM; | ||
| 1745 | goto bail; | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | ret = pci_register_driver(&ipath_driver); | ||
| 1749 | if (ret < 0) { | ||
| 1750 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 1751 | ": Unable to register driver: error %d\n", -ret); | ||
| 1752 | goto bail_unit; | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | ret = ipath_driver_create_group(&ipath_driver.driver); | ||
| 1756 | if (ret < 0) { | ||
| 1757 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create driver " | ||
| 1758 | "sysfs entries: error %d\n", -ret); | ||
| 1759 | goto bail_pci; | ||
| 1760 | } | ||
| 1761 | |||
| 1762 | ret = ipath_init_ipathfs(); | ||
| 1763 | if (ret < 0) { | ||
| 1764 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " | ||
| 1765 | "ipathfs: error %d\n", -ret); | ||
| 1766 | goto bail_group; | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | goto bail; | ||
| 1770 | |||
| 1771 | bail_group: | ||
| 1772 | ipath_driver_remove_group(&ipath_driver.driver); | ||
| 1773 | |||
| 1774 | bail_pci: | ||
| 1775 | pci_unregister_driver(&ipath_driver); | ||
| 1776 | |||
| 1777 | bail_unit: | ||
| 1778 | idr_destroy(&unit_table); | ||
| 1779 | |||
| 1780 | bail: | ||
| 1781 | return ret; | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | static void cleanup_device(struct ipath_devdata *dd) | ||
| 1785 | { | ||
| 1786 | int port; | ||
| 1787 | |||
| 1788 | ipath_shutdown_device(dd); | ||
| 1789 | |||
| 1790 | if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) { | ||
| 1791 | /* can't do anything more with chip; needs re-init */ | ||
| 1792 | *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT; | ||
| 1793 | if (dd->ipath_kregbase) { | ||
| 1794 | /* | ||
| 1795 | * if we haven't already cleaned up before these are | ||
| 1796 | * to ensure any register reads/writes "fail" until | ||
| 1797 | * re-init | ||
| 1798 | */ | ||
| 1799 | dd->ipath_kregbase = NULL; | ||
| 1800 | dd->ipath_kregvirt = NULL; | ||
| 1801 | dd->ipath_uregbase = 0; | ||
| 1802 | dd->ipath_sregbase = 0; | ||
| 1803 | dd->ipath_cregbase = 0; | ||
| 1804 | dd->ipath_kregsize = 0; | ||
| 1805 | } | ||
| 1806 | ipath_disable_wc(dd); | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | if (dd->ipath_pioavailregs_dma) { | ||
| 1810 | dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, | ||
| 1811 | (void *) dd->ipath_pioavailregs_dma, | ||
| 1812 | dd->ipath_pioavailregs_phys); | ||
| 1813 | dd->ipath_pioavailregs_dma = NULL; | ||
| 1814 | } | ||
| 1815 | |||
| 1816 | if (dd->ipath_pageshadow) { | ||
| 1817 | struct page **tmpp = dd->ipath_pageshadow; | ||
| 1818 | int i, cnt = 0; | ||
| 1819 | |||
| 1820 | ipath_cdbg(VERBOSE, "Unlocking any expTID pages still " | ||
| 1821 | "locked\n"); | ||
| 1822 | for (port = 0; port < dd->ipath_cfgports; port++) { | ||
| 1823 | int port_tidbase = port * dd->ipath_rcvtidcnt; | ||
| 1824 | int maxtid = port_tidbase + dd->ipath_rcvtidcnt; | ||
| 1825 | for (i = port_tidbase; i < maxtid; i++) { | ||
| 1826 | if (!tmpp[i]) | ||
| 1827 | continue; | ||
| 1828 | ipath_release_user_pages(&tmpp[i], 1); | ||
| 1829 | tmpp[i] = NULL; | ||
| 1830 | cnt++; | ||
| 1831 | } | ||
| 1832 | } | ||
| 1833 | if (cnt) { | ||
| 1834 | ipath_stats.sps_pageunlocks += cnt; | ||
| 1835 | ipath_cdbg(VERBOSE, "There were still %u expTID " | ||
| 1836 | "entries locked\n", cnt); | ||
| 1837 | } | ||
| 1838 | if (ipath_stats.sps_pagelocks || | ||
| 1839 | ipath_stats.sps_pageunlocks) | ||
| 1840 | ipath_cdbg(VERBOSE, "%llu pages locked, %llu " | ||
| 1841 | "unlocked via ipath_m{un}lock\n", | ||
| 1842 | (unsigned long long) | ||
| 1843 | ipath_stats.sps_pagelocks, | ||
| 1844 | (unsigned long long) | ||
| 1845 | ipath_stats.sps_pageunlocks); | ||
| 1846 | |||
| 1847 | ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n", | ||
| 1848 | dd->ipath_pageshadow); | ||
| 1849 | vfree(dd->ipath_pageshadow); | ||
| 1850 | dd->ipath_pageshadow = NULL; | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | /* | ||
| 1854 | * free any resources still in use (usually just kernel ports) | ||
| 1855 | * at unload | ||
| 1856 | */ | ||
| 1857 | for (port = 0; port < dd->ipath_cfgports; port++) | ||
| 1858 | ipath_free_pddata(dd, port, 1); | ||
| 1859 | kfree(dd->ipath_pd); | ||
| 1860 | /* | ||
| 1861 | * debuggability, in case some cleanup path tries to use it | ||
| 1862 | * after this | ||
| 1863 | */ | ||
| 1864 | dd->ipath_pd = NULL; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | static void __exit infinipath_cleanup(void) | ||
| 1868 | { | ||
| 1869 | struct ipath_devdata *dd, *tmp; | ||
| 1870 | unsigned long flags; | ||
| 1871 | |||
| 1872 | ipath_exit_ipathfs(); | ||
| 1873 | |||
| 1874 | ipath_driver_remove_group(&ipath_driver.driver); | ||
| 1875 | |||
| 1876 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 1877 | |||
| 1878 | /* | ||
| 1879 | * turn off rcv, send, and interrupts for all ports, all drivers | ||
| 1880 | * should also hard reset the chip here? | ||
| 1881 | * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs | ||
| 1882 | * for all versions of the driver, if they were allocated | ||
| 1883 | */ | ||
| 1884 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 1885 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 1886 | |||
| 1887 | if (dd->ipath_kregbase) | ||
| 1888 | cleanup_device(dd); | ||
| 1889 | |||
| 1890 | if (dd->pcidev) { | ||
| 1891 | if (dd->pcidev->irq) { | ||
| 1892 | ipath_cdbg(VERBOSE, | ||
| 1893 | "unit %u free_irq of irq %x\n", | ||
| 1894 | dd->ipath_unit, dd->pcidev->irq); | ||
| 1895 | free_irq(dd->pcidev->irq, dd); | ||
| 1896 | } else | ||
| 1897 | ipath_dbg("irq is 0, not doing free_irq " | ||
| 1898 | "for unit %u\n", dd->ipath_unit); | ||
| 1899 | dd->pcidev = NULL; | ||
| 1900 | } | ||
| 1901 | |||
| 1902 | /* | ||
| 1903 | * we check for NULL here, because it's outside the kregbase | ||
| 1904 | * check, and we need to call it after the free_irq. Thus | ||
| 1905 | * it's possible that the function pointers were never | ||
| 1906 | * initialized. | ||
| 1907 | */ | ||
| 1908 | if (dd->ipath_f_cleanup) | ||
| 1909 | /* clean up chip-specific stuff */ | ||
| 1910 | dd->ipath_f_cleanup(dd); | ||
| 1911 | |||
| 1912 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 1916 | |||
| 1917 | ipath_cdbg(VERBOSE, "Unregistering pci driver\n"); | ||
| 1918 | pci_unregister_driver(&ipath_driver); | ||
| 1919 | |||
| 1920 | idr_destroy(&unit_table); | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | /** | ||
| 1924 | * ipath_reset_device - reset the chip if possible | ||
| 1925 | * @unit: the device to reset | ||
| 1926 | * | ||
| 1927 | * Whether or not reset is successful, we attempt to re-initialize the chip | ||
| 1928 | * (that is, much like a driver unload/reload). We clear the INITTED flag | ||
| 1929 | * so that the various entry points will fail until we reinitialize. For | ||
| 1930 | * now, we only allow this if no user ports are open that use chip resources | ||
| 1931 | */ | ||
| 1932 | int ipath_reset_device(int unit) | ||
| 1933 | { | ||
| 1934 | int ret, i; | ||
| 1935 | struct ipath_devdata *dd = ipath_lookup(unit); | ||
| 1936 | |||
| 1937 | if (!dd) { | ||
| 1938 | ret = -ENODEV; | ||
| 1939 | goto bail; | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | dev_info(&dd->pcidev->dev, "Reset on unit %u requested\n", unit); | ||
| 1943 | |||
| 1944 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) { | ||
| 1945 | dev_info(&dd->pcidev->dev, "Invalid unit number %u or " | ||
| 1946 | "not initialized or not present\n", unit); | ||
| 1947 | ret = -ENXIO; | ||
| 1948 | goto bail; | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | if (dd->ipath_pd) | ||
| 1952 | for (i = 1; i < dd->ipath_portcnt; i++) { | ||
| 1953 | if (dd->ipath_pd[i] && dd->ipath_pd[i]->port_cnt) { | ||
| 1954 | ipath_dbg("unit %u port %d is in use " | ||
| 1955 | "(PID %u cmd %s), can't reset\n", | ||
| 1956 | unit, i, | ||
| 1957 | dd->ipath_pd[i]->port_pid, | ||
| 1958 | dd->ipath_pd[i]->port_comm); | ||
| 1959 | ret = -EBUSY; | ||
| 1960 | goto bail; | ||
| 1961 | } | ||
| 1962 | } | ||
| 1963 | |||
| 1964 | dd->ipath_flags &= ~IPATH_INITTED; | ||
| 1965 | ret = dd->ipath_f_reset(dd); | ||
| 1966 | if (ret != 1) | ||
| 1967 | ipath_dbg("reset was not successful\n"); | ||
| 1968 | ipath_dbg("Trying to reinitialize unit %u after reset attempt\n", | ||
| 1969 | unit); | ||
| 1970 | ret = ipath_init_chip(dd, 1); | ||
| 1971 | if (ret) | ||
| 1972 | ipath_dev_err(dd, "Reinitialize unit %u after " | ||
| 1973 | "reset failed with %d\n", unit, ret); | ||
| 1974 | else | ||
| 1975 | dev_info(&dd->pcidev->dev, "Reinitialized unit %u after " | ||
| 1976 | "resetting\n", unit); | ||
| 1977 | |||
| 1978 | bail: | ||
| 1979 | return ret; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | module_init(infinipath_init); | ||
| 1983 | module_exit(infinipath_cleanup); | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c new file mode 100644 index 000000000000..f11a900e8cd7 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c | |||
| @@ -0,0 +1,613 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/delay.h> | ||
| 34 | #include <linux/pci.h> | ||
| 35 | #include <linux/vmalloc.h> | ||
| 36 | |||
| 37 | #include "ipath_kernel.h" | ||
| 38 | |||
| 39 | /* | ||
| 40 | * InfiniPath I2C driver for a serial eeprom. This is not a generic | ||
| 41 | * I2C interface. For a start, the device we're using (Atmel AT24C11) | ||
| 42 | * doesn't work like a regular I2C device. It looks like one | ||
| 43 | * electrically, but not logically. Normal I2C devices have a single | ||
| 44 | * 7-bit or 10-bit I2C address that they respond to. Valid 7-bit | ||
| 45 | * addresses range from 0x03 to 0x77. Addresses 0x00 to 0x02 and 0x78 | ||
| 46 | * to 0x7F are special reserved addresses (e.g. 0x00 is the "general | ||
| 47 | * call" address.) The Atmel device, on the other hand, responds to ALL | ||
| 48 | * 7-bit addresses. It's designed to be the only device on a given I2C | ||
| 49 | * bus. A 7-bit address corresponds to the memory address within the | ||
| 50 | * Atmel device itself. | ||
| 51 | * | ||
| 52 | * Also, the timing requirements mean more than simple software | ||
| 53 | * bitbanging, with readbacks from chip to ensure timing (simple udelay | ||
| 54 | * is not enough). | ||
| 55 | * | ||
| 56 | * This all means that accessing the device is specialized enough | ||
| 57 | * that using the standard kernel I2C bitbanging interface would be | ||
| 58 | * impossible. For example, the core I2C eeprom driver expects to find | ||
| 59 | * a device at one or more of a limited set of addresses only. It doesn't | ||
| 60 | * allow writing to an eeprom. It also doesn't provide any means of | ||
| 61 | * accessing eeprom contents from within the kernel, only via sysfs. | ||
| 62 | */ | ||
| 63 | |||
| 64 | enum i2c_type { | ||
| 65 | i2c_line_scl = 0, | ||
| 66 | i2c_line_sda | ||
| 67 | }; | ||
| 68 | |||
| 69 | enum i2c_state { | ||
| 70 | i2c_line_low = 0, | ||
| 71 | i2c_line_high | ||
| 72 | }; | ||
| 73 | |||
| 74 | #define READ_CMD 1 | ||
| 75 | #define WRITE_CMD 0 | ||
| 76 | |||
| 77 | static int eeprom_init; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * The gpioval manipulation really should be protected by spinlocks | ||
| 81 | * or be converted to use atomic operations. | ||
| 82 | */ | ||
| 83 | |||
| 84 | /** | ||
| 85 | * i2c_gpio_set - set a GPIO line | ||
| 86 | * @dd: the infinipath device | ||
| 87 | * @line: the line to set | ||
| 88 | * @new_line_state: the state to set | ||
| 89 | * | ||
| 90 | * Returns 0 if the line was set to the new state successfully, non-zero | ||
| 91 | * on error. | ||
| 92 | */ | ||
| 93 | static int i2c_gpio_set(struct ipath_devdata *dd, | ||
| 94 | enum i2c_type line, | ||
| 95 | enum i2c_state new_line_state) | ||
| 96 | { | ||
| 97 | u64 read_val, write_val, mask, *gpioval; | ||
| 98 | |||
| 99 | gpioval = &dd->ipath_gpio_out; | ||
| 100 | read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl); | ||
| 101 | if (line == i2c_line_scl) | ||
| 102 | mask = ipath_gpio_scl; | ||
| 103 | else | ||
| 104 | mask = ipath_gpio_sda; | ||
| 105 | |||
| 106 | if (new_line_state == i2c_line_high) | ||
| 107 | /* tri-state the output rather than force high */ | ||
| 108 | write_val = read_val & ~mask; | ||
| 109 | else | ||
| 110 | /* config line to be an output */ | ||
| 111 | write_val = read_val | mask; | ||
| 112 | ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val); | ||
| 113 | |||
| 114 | /* set high and verify */ | ||
| 115 | if (new_line_state == i2c_line_high) | ||
| 116 | write_val = 0x1UL; | ||
| 117 | else | ||
| 118 | write_val = 0x0UL; | ||
| 119 | |||
| 120 | if (line == i2c_line_scl) { | ||
| 121 | write_val <<= ipath_gpio_scl_num; | ||
| 122 | *gpioval = *gpioval & ~(1UL << ipath_gpio_scl_num); | ||
| 123 | *gpioval |= write_val; | ||
| 124 | } else { | ||
| 125 | write_val <<= ipath_gpio_sda_num; | ||
| 126 | *gpioval = *gpioval & ~(1UL << ipath_gpio_sda_num); | ||
| 127 | *gpioval |= write_val; | ||
| 128 | } | ||
| 129 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval); | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * i2c_gpio_get - get a GPIO line state | ||
| 136 | * @dd: the infinipath device | ||
| 137 | * @line: the line to get | ||
| 138 | * @curr_statep: where to put the line state | ||
| 139 | * | ||
| 140 | * Returns 0 if the line was set to the new state successfully, non-zero | ||
| 141 | * on error. curr_state is not set on error. | ||
| 142 | */ | ||
| 143 | static int i2c_gpio_get(struct ipath_devdata *dd, | ||
| 144 | enum i2c_type line, | ||
| 145 | enum i2c_state *curr_statep) | ||
| 146 | { | ||
| 147 | u64 read_val, write_val, mask; | ||
| 148 | int ret; | ||
| 149 | |||
| 150 | /* check args */ | ||
| 151 | if (curr_statep == NULL) { | ||
| 152 | ret = 1; | ||
| 153 | goto bail; | ||
| 154 | } | ||
| 155 | |||
| 156 | read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl); | ||
| 157 | /* config line to be an input */ | ||
| 158 | if (line == i2c_line_scl) | ||
| 159 | mask = ipath_gpio_scl; | ||
| 160 | else | ||
| 161 | mask = ipath_gpio_sda; | ||
| 162 | write_val = read_val & ~mask; | ||
| 163 | ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val); | ||
| 164 | read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); | ||
| 165 | |||
| 166 | if (read_val & mask) | ||
| 167 | *curr_statep = i2c_line_high; | ||
| 168 | else | ||
| 169 | *curr_statep = i2c_line_low; | ||
| 170 | |||
| 171 | ret = 0; | ||
| 172 | |||
| 173 | bail: | ||
| 174 | return ret; | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * i2c_wait_for_writes - wait for a write | ||
| 179 | * @dd: the infinipath device | ||
| 180 | * | ||
| 181 | * We use this instead of udelay directly, so we can make sure | ||
| 182 | * that previous register writes have been flushed all the way | ||
| 183 | * to the chip. Since we are delaying anyway, the cost doesn't | ||
| 184 | * hurt, and makes the bit twiddling more regular | ||
| 185 | */ | ||
| 186 | static void i2c_wait_for_writes(struct ipath_devdata *dd) | ||
| 187 | { | ||
| 188 | (void)ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); | ||
| 189 | } | ||
| 190 | |||
| 191 | static void scl_out(struct ipath_devdata *dd, u8 bit) | ||
| 192 | { | ||
| 193 | i2c_gpio_set(dd, i2c_line_scl, bit ? i2c_line_high : i2c_line_low); | ||
| 194 | |||
| 195 | i2c_wait_for_writes(dd); | ||
| 196 | } | ||
| 197 | |||
| 198 | static void sda_out(struct ipath_devdata *dd, u8 bit) | ||
| 199 | { | ||
| 200 | i2c_gpio_set(dd, i2c_line_sda, bit ? i2c_line_high : i2c_line_low); | ||
| 201 | |||
| 202 | i2c_wait_for_writes(dd); | ||
| 203 | } | ||
| 204 | |||
| 205 | static u8 sda_in(struct ipath_devdata *dd, int wait) | ||
| 206 | { | ||
| 207 | enum i2c_state bit; | ||
| 208 | |||
| 209 | if (i2c_gpio_get(dd, i2c_line_sda, &bit)) | ||
| 210 | ipath_dbg("get bit failed!\n"); | ||
| 211 | |||
| 212 | if (wait) | ||
| 213 | i2c_wait_for_writes(dd); | ||
| 214 | |||
| 215 | return bit == i2c_line_high ? 1U : 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * i2c_ackrcv - see if ack following write is true | ||
| 220 | * @dd: the infinipath device | ||
| 221 | */ | ||
| 222 | static int i2c_ackrcv(struct ipath_devdata *dd) | ||
| 223 | { | ||
| 224 | u8 ack_received; | ||
| 225 | |||
| 226 | /* AT ENTRY SCL = LOW */ | ||
| 227 | /* change direction, ignore data */ | ||
| 228 | ack_received = sda_in(dd, 1); | ||
| 229 | scl_out(dd, i2c_line_high); | ||
| 230 | ack_received = sda_in(dd, 1) == 0; | ||
| 231 | scl_out(dd, i2c_line_low); | ||
| 232 | return ack_received; | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * wr_byte - write a byte, one bit at a time | ||
| 237 | * @dd: the infinipath device | ||
| 238 | * @data: the byte to write | ||
| 239 | * | ||
| 240 | * Returns 0 if we got the following ack, otherwise 1 | ||
| 241 | */ | ||
| 242 | static int wr_byte(struct ipath_devdata *dd, u8 data) | ||
| 243 | { | ||
| 244 | int bit_cntr; | ||
| 245 | u8 bit; | ||
| 246 | |||
| 247 | for (bit_cntr = 7; bit_cntr >= 0; bit_cntr--) { | ||
| 248 | bit = (data >> bit_cntr) & 1; | ||
| 249 | sda_out(dd, bit); | ||
| 250 | scl_out(dd, i2c_line_high); | ||
| 251 | scl_out(dd, i2c_line_low); | ||
| 252 | } | ||
| 253 | return (!i2c_ackrcv(dd)) ? 1 : 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | static void send_ack(struct ipath_devdata *dd) | ||
| 257 | { | ||
| 258 | sda_out(dd, i2c_line_low); | ||
| 259 | scl_out(dd, i2c_line_high); | ||
| 260 | scl_out(dd, i2c_line_low); | ||
| 261 | sda_out(dd, i2c_line_high); | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * i2c_startcmd - transmit the start condition, followed by address/cmd | ||
| 266 | * @dd: the infinipath device | ||
| 267 | * @offset_dir: direction byte | ||
| 268 | * | ||
| 269 | * (both clock/data high, clock high, data low while clock is high) | ||
| 270 | */ | ||
| 271 | static int i2c_startcmd(struct ipath_devdata *dd, u8 offset_dir) | ||
| 272 | { | ||
| 273 | int res; | ||
| 274 | |||
| 275 | /* issue start sequence */ | ||
| 276 | sda_out(dd, i2c_line_high); | ||
| 277 | scl_out(dd, i2c_line_high); | ||
| 278 | sda_out(dd, i2c_line_low); | ||
| 279 | scl_out(dd, i2c_line_low); | ||
| 280 | |||
| 281 | /* issue length and direction byte */ | ||
| 282 | res = wr_byte(dd, offset_dir); | ||
| 283 | |||
| 284 | if (res) | ||
| 285 | ipath_cdbg(VERBOSE, "No ack to complete start\n"); | ||
| 286 | |||
| 287 | return res; | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * stop_cmd - transmit the stop condition | ||
| 292 | * @dd: the infinipath device | ||
| 293 | * | ||
| 294 | * (both clock/data low, clock high, data high while clock is high) | ||
| 295 | */ | ||
| 296 | static void stop_cmd(struct ipath_devdata *dd) | ||
| 297 | { | ||
| 298 | scl_out(dd, i2c_line_low); | ||
| 299 | sda_out(dd, i2c_line_low); | ||
| 300 | scl_out(dd, i2c_line_high); | ||
| 301 | sda_out(dd, i2c_line_high); | ||
| 302 | udelay(2); | ||
| 303 | } | ||
| 304 | |||
| 305 | /** | ||
| 306 | * eeprom_reset - reset I2C communication | ||
| 307 | * @dd: the infinipath device | ||
| 308 | */ | ||
| 309 | |||
| 310 | static int eeprom_reset(struct ipath_devdata *dd) | ||
| 311 | { | ||
| 312 | int clock_cycles_left = 9; | ||
| 313 | u64 *gpioval = &dd->ipath_gpio_out; | ||
| 314 | int ret; | ||
| 315 | |||
| 316 | eeprom_init = 1; | ||
| 317 | *gpioval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_out); | ||
| 318 | ipath_cdbg(VERBOSE, "Resetting i2c eeprom; initial gpioout reg " | ||
| 319 | "is %llx\n", (unsigned long long) *gpioval); | ||
| 320 | |||
| 321 | /* | ||
| 322 | * This is to get the i2c into a known state, by first going low, | ||
| 323 | * then tristate sda (and then tristate scl as first thing | ||
| 324 | * in loop) | ||
| 325 | */ | ||
| 326 | scl_out(dd, i2c_line_low); | ||
| 327 | sda_out(dd, i2c_line_high); | ||
| 328 | |||
| 329 | while (clock_cycles_left--) { | ||
| 330 | scl_out(dd, i2c_line_high); | ||
| 331 | |||
| 332 | if (sda_in(dd, 0)) { | ||
| 333 | sda_out(dd, i2c_line_low); | ||
| 334 | scl_out(dd, i2c_line_low); | ||
| 335 | ret = 0; | ||
| 336 | goto bail; | ||
| 337 | } | ||
| 338 | |||
| 339 | scl_out(dd, i2c_line_low); | ||
| 340 | } | ||
| 341 | |||
| 342 | ret = 1; | ||
| 343 | |||
| 344 | bail: | ||
| 345 | return ret; | ||
| 346 | } | ||
| 347 | |||
| 348 | /** | ||
| 349 | * ipath_eeprom_read - receives bytes from the eeprom via I2C | ||
| 350 | * @dd: the infinipath device | ||
| 351 | * @eeprom_offset: address to read from | ||
| 352 | * @buffer: where to store result | ||
| 353 | * @len: number of bytes to receive | ||
| 354 | */ | ||
| 355 | |||
| 356 | int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset, | ||
| 357 | void *buffer, int len) | ||
| 358 | { | ||
| 359 | /* compiler complains unless initialized */ | ||
| 360 | u8 single_byte = 0; | ||
| 361 | int bit_cntr; | ||
| 362 | int ret; | ||
| 363 | |||
| 364 | if (!eeprom_init) | ||
| 365 | eeprom_reset(dd); | ||
| 366 | |||
| 367 | eeprom_offset = (eeprom_offset << 1) | READ_CMD; | ||
| 368 | |||
| 369 | if (i2c_startcmd(dd, eeprom_offset)) { | ||
| 370 | ipath_dbg("Failed startcmd\n"); | ||
| 371 | stop_cmd(dd); | ||
| 372 | ret = 1; | ||
| 373 | goto bail; | ||
| 374 | } | ||
| 375 | |||
| 376 | /* | ||
| 377 | * eeprom keeps clocking data out as long as we ack, automatically | ||
| 378 | * incrementing the address. | ||
| 379 | */ | ||
| 380 | while (len-- > 0) { | ||
| 381 | /* get data */ | ||
| 382 | single_byte = 0; | ||
| 383 | for (bit_cntr = 8; bit_cntr; bit_cntr--) { | ||
| 384 | u8 bit; | ||
| 385 | scl_out(dd, i2c_line_high); | ||
| 386 | bit = sda_in(dd, 0); | ||
| 387 | single_byte |= bit << (bit_cntr - 1); | ||
| 388 | scl_out(dd, i2c_line_low); | ||
| 389 | } | ||
| 390 | |||
| 391 | /* send ack if not the last byte */ | ||
| 392 | if (len) | ||
| 393 | send_ack(dd); | ||
| 394 | |||
| 395 | *((u8 *) buffer) = single_byte; | ||
| 396 | buffer++; | ||
| 397 | } | ||
| 398 | |||
| 399 | stop_cmd(dd); | ||
| 400 | |||
| 401 | ret = 0; | ||
| 402 | |||
| 403 | bail: | ||
| 404 | return ret; | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | ||
| 408 | * ipath_eeprom_write - writes data to the eeprom via I2C | ||
| 409 | * @dd: the infinipath device | ||
| 410 | * @eeprom_offset: where to place data | ||
| 411 | * @buffer: data to write | ||
| 412 | * @len: number of bytes to write | ||
| 413 | */ | ||
| 414 | int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset, | ||
| 415 | const void *buffer, int len) | ||
| 416 | { | ||
| 417 | u8 single_byte; | ||
| 418 | int sub_len; | ||
| 419 | const u8 *bp = buffer; | ||
| 420 | int max_wait_time, i; | ||
| 421 | int ret; | ||
| 422 | |||
| 423 | if (!eeprom_init) | ||
| 424 | eeprom_reset(dd); | ||
| 425 | |||
| 426 | while (len > 0) { | ||
| 427 | if (i2c_startcmd(dd, (eeprom_offset << 1) | WRITE_CMD)) { | ||
| 428 | ipath_dbg("Failed to start cmd offset %u\n", | ||
| 429 | eeprom_offset); | ||
| 430 | goto failed_write; | ||
| 431 | } | ||
| 432 | |||
| 433 | sub_len = min(len, 4); | ||
| 434 | eeprom_offset += sub_len; | ||
| 435 | len -= sub_len; | ||
| 436 | |||
| 437 | for (i = 0; i < sub_len; i++) { | ||
| 438 | if (wr_byte(dd, *bp++)) { | ||
| 439 | ipath_dbg("no ack after byte %u/%u (%u " | ||
| 440 | "total remain)\n", i, sub_len, | ||
| 441 | len + sub_len - i); | ||
| 442 | goto failed_write; | ||
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | stop_cmd(dd); | ||
| 447 | |||
| 448 | /* | ||
| 449 | * wait for write complete by waiting for a successful | ||
| 450 | * read (the chip replies with a zero after the write | ||
| 451 | * cmd completes, and before it writes to the eeprom. | ||
| 452 | * The startcmd for the read will fail the ack until | ||
| 453 | * the writes have completed. We do this inline to avoid | ||
| 454 | * the debug prints that are in the real read routine | ||
| 455 | * if the startcmd fails. | ||
| 456 | */ | ||
| 457 | max_wait_time = 100; | ||
| 458 | while (i2c_startcmd(dd, READ_CMD)) { | ||
| 459 | stop_cmd(dd); | ||
| 460 | if (!--max_wait_time) { | ||
| 461 | ipath_dbg("Did not get successful read to " | ||
| 462 | "complete write\n"); | ||
| 463 | goto failed_write; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | /* now read the zero byte */ | ||
| 467 | for (i = single_byte = 0; i < 8; i++) { | ||
| 468 | u8 bit; | ||
| 469 | scl_out(dd, i2c_line_high); | ||
| 470 | bit = sda_in(dd, 0); | ||
| 471 | scl_out(dd, i2c_line_low); | ||
| 472 | single_byte <<= 1; | ||
| 473 | single_byte |= bit; | ||
| 474 | } | ||
| 475 | stop_cmd(dd); | ||
| 476 | } | ||
| 477 | |||
| 478 | ret = 0; | ||
| 479 | goto bail; | ||
| 480 | |||
| 481 | failed_write: | ||
| 482 | stop_cmd(dd); | ||
| 483 | ret = 1; | ||
| 484 | |||
| 485 | bail: | ||
| 486 | return ret; | ||
| 487 | } | ||
| 488 | |||
| 489 | static u8 flash_csum(struct ipath_flash *ifp, int adjust) | ||
| 490 | { | ||
| 491 | u8 *ip = (u8 *) ifp; | ||
| 492 | u8 csum = 0, len; | ||
| 493 | |||
| 494 | for (len = 0; len < ifp->if_length; len++) | ||
| 495 | csum += *ip++; | ||
| 496 | csum -= ifp->if_csum; | ||
| 497 | csum = ~csum; | ||
| 498 | if (adjust) | ||
| 499 | ifp->if_csum = csum; | ||
| 500 | |||
| 501 | return csum; | ||
| 502 | } | ||
| 503 | |||
| 504 | /** | ||
| 505 | * ipath_get_guid - get the GUID from the i2c device | ||
| 506 | * @dd: the infinipath device | ||
| 507 | * | ||
| 508 | * When we add the multi-chip support, we will probably have to add | ||
| 509 | * the ability to use the number of guids field, and get the guid from | ||
| 510 | * the first chip's flash, to use for all of them. | ||
| 511 | */ | ||
| 512 | void ipath_get_guid(struct ipath_devdata *dd) | ||
| 513 | { | ||
| 514 | void *buf; | ||
| 515 | struct ipath_flash *ifp; | ||
| 516 | __be64 guid; | ||
| 517 | int len; | ||
| 518 | u8 csum, *bguid; | ||
| 519 | int t = dd->ipath_unit; | ||
| 520 | struct ipath_devdata *dd0 = ipath_lookup(0); | ||
| 521 | |||
| 522 | if (t && dd0->ipath_nguid > 1 && t <= dd0->ipath_nguid) { | ||
| 523 | u8 *bguid, oguid; | ||
| 524 | dd->ipath_guid = dd0->ipath_guid; | ||
| 525 | bguid = (u8 *) & dd->ipath_guid; | ||
| 526 | |||
| 527 | oguid = bguid[7]; | ||
| 528 | bguid[7] += t; | ||
| 529 | if (oguid > bguid[7]) { | ||
| 530 | if (bguid[6] == 0xff) { | ||
| 531 | if (bguid[5] == 0xff) { | ||
| 532 | ipath_dev_err( | ||
| 533 | dd, | ||
| 534 | "Can't set %s GUID from " | ||
| 535 | "base, wraps to OUI!\n", | ||
| 536 | ipath_get_unit_name(t)); | ||
| 537 | dd->ipath_guid = 0; | ||
| 538 | goto bail; | ||
| 539 | } | ||
| 540 | bguid[5]++; | ||
| 541 | } | ||
| 542 | bguid[6]++; | ||
| 543 | } | ||
| 544 | dd->ipath_nguid = 1; | ||
| 545 | |||
| 546 | ipath_dbg("nguid %u, so adding %u to device 0 guid, " | ||
| 547 | "for %llx\n", | ||
| 548 | dd0->ipath_nguid, t, | ||
| 549 | (unsigned long long) be64_to_cpu(dd->ipath_guid)); | ||
| 550 | goto bail; | ||
| 551 | } | ||
| 552 | |||
| 553 | len = offsetof(struct ipath_flash, if_future); | ||
| 554 | buf = vmalloc(len); | ||
| 555 | if (!buf) { | ||
| 556 | ipath_dev_err(dd, "Couldn't allocate memory to read %u " | ||
| 557 | "bytes from eeprom for GUID\n", len); | ||
| 558 | goto bail; | ||
| 559 | } | ||
| 560 | |||
| 561 | if (ipath_eeprom_read(dd, 0, buf, len)) { | ||
| 562 | ipath_dev_err(dd, "Failed reading GUID from eeprom\n"); | ||
| 563 | goto done; | ||
| 564 | } | ||
| 565 | ifp = (struct ipath_flash *)buf; | ||
| 566 | |||
| 567 | csum = flash_csum(ifp, 0); | ||
| 568 | if (csum != ifp->if_csum) { | ||
| 569 | dev_info(&dd->pcidev->dev, "Bad I2C flash checksum: " | ||
| 570 | "0x%x, not 0x%x\n", csum, ifp->if_csum); | ||
| 571 | goto done; | ||
| 572 | } | ||
| 573 | if (*(__be64 *) ifp->if_guid == 0ULL || | ||
| 574 | *(__be64 *) ifp->if_guid == __constant_cpu_to_be64(-1LL)) { | ||
| 575 | ipath_dev_err(dd, "Invalid GUID %llx from flash; " | ||
| 576 | "ignoring\n", | ||
| 577 | *(unsigned long long *) ifp->if_guid); | ||
| 578 | /* don't allow GUID if all 0 or all 1's */ | ||
| 579 | goto done; | ||
| 580 | } | ||
| 581 | |||
| 582 | /* complain, but allow it */ | ||
| 583 | if (*(u64 *) ifp->if_guid == 0x100007511000000ULL) | ||
| 584 | dev_info(&dd->pcidev->dev, "Warning, GUID %llx is " | ||
| 585 | "default, probably not correct!\n", | ||
| 586 | *(unsigned long long *) ifp->if_guid); | ||
| 587 | |||
| 588 | bguid = ifp->if_guid; | ||
| 589 | if (!bguid[0] && !bguid[1] && !bguid[2]) { | ||
| 590 | /* original incorrect GUID format in flash; fix in | ||
| 591 | * core copy, by shifting up 2 octets; don't need to | ||
| 592 | * change top octet, since both it and shifted are | ||
| 593 | * 0.. */ | ||
| 594 | bguid[1] = bguid[3]; | ||
| 595 | bguid[2] = bguid[4]; | ||
| 596 | bguid[3] = bguid[4] = 0; | ||
| 597 | guid = *(__be64 *) ifp->if_guid; | ||
| 598 | ipath_cdbg(VERBOSE, "Old GUID format in flash, top 3 zero, " | ||
| 599 | "shifting 2 octets\n"); | ||
| 600 | } else | ||
| 601 | guid = *(__be64 *) ifp->if_guid; | ||
| 602 | dd->ipath_guid = guid; | ||
| 603 | dd->ipath_nguid = ifp->if_numguid; | ||
| 604 | memcpy(dd->ipath_serial, ifp->if_serial, | ||
| 605 | sizeof(ifp->if_serial)); | ||
| 606 | ipath_cdbg(VERBOSE, "Initted GUID to %llx from eeprom\n", | ||
| 607 | (unsigned long long) be64_to_cpu(dd->ipath_guid)); | ||
| 608 | |||
| 609 | done: | ||
| 610 | vfree(buf); | ||
| 611 | |||
| 612 | bail:; | ||
| 613 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c new file mode 100644 index 000000000000..c347191f02bf --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
| @@ -0,0 +1,1910 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/pci.h> | ||
| 34 | #include <linux/poll.h> | ||
| 35 | #include <linux/cdev.h> | ||
| 36 | #include <linux/swap.h> | ||
| 37 | #include <linux/vmalloc.h> | ||
| 38 | #include <asm/pgtable.h> | ||
| 39 | |||
| 40 | #include "ipath_kernel.h" | ||
| 41 | #include "ips_common.h" | ||
| 42 | #include "ipath_layer.h" | ||
| 43 | |||
| 44 | static int ipath_open(struct inode *, struct file *); | ||
| 45 | static int ipath_close(struct inode *, struct file *); | ||
| 46 | static ssize_t ipath_write(struct file *, const char __user *, size_t, | ||
| 47 | loff_t *); | ||
| 48 | static unsigned int ipath_poll(struct file *, struct poll_table_struct *); | ||
| 49 | static int ipath_mmap(struct file *, struct vm_area_struct *); | ||
| 50 | |||
| 51 | static struct file_operations ipath_file_ops = { | ||
| 52 | .owner = THIS_MODULE, | ||
| 53 | .write = ipath_write, | ||
| 54 | .open = ipath_open, | ||
| 55 | .release = ipath_close, | ||
| 56 | .poll = ipath_poll, | ||
| 57 | .mmap = ipath_mmap | ||
| 58 | }; | ||
| 59 | |||
| 60 | static int ipath_get_base_info(struct ipath_portdata *pd, | ||
| 61 | void __user *ubase, size_t ubase_size) | ||
| 62 | { | ||
| 63 | int ret = 0; | ||
| 64 | struct ipath_base_info *kinfo = NULL; | ||
| 65 | struct ipath_devdata *dd = pd->port_dd; | ||
| 66 | |||
| 67 | if (ubase_size < sizeof(*kinfo)) { | ||
| 68 | ipath_cdbg(PROC, | ||
| 69 | "Base size %lu, need %lu (version mismatch?)\n", | ||
| 70 | (unsigned long) ubase_size, | ||
| 71 | (unsigned long) sizeof(*kinfo)); | ||
| 72 | ret = -EINVAL; | ||
| 73 | goto bail; | ||
| 74 | } | ||
| 75 | |||
| 76 | kinfo = kzalloc(sizeof(*kinfo), GFP_KERNEL); | ||
| 77 | if (kinfo == NULL) { | ||
| 78 | ret = -ENOMEM; | ||
| 79 | goto bail; | ||
| 80 | } | ||
| 81 | |||
| 82 | ret = dd->ipath_f_get_base_info(pd, kinfo); | ||
| 83 | if (ret < 0) | ||
| 84 | goto bail; | ||
| 85 | |||
| 86 | kinfo->spi_rcvhdr_cnt = dd->ipath_rcvhdrcnt; | ||
| 87 | kinfo->spi_rcvhdrent_size = dd->ipath_rcvhdrentsize; | ||
| 88 | kinfo->spi_tidegrcnt = dd->ipath_rcvegrcnt; | ||
| 89 | kinfo->spi_rcv_egrbufsize = dd->ipath_rcvegrbufsize; | ||
| 90 | /* | ||
| 91 | * have to mmap whole thing | ||
| 92 | */ | ||
| 93 | kinfo->spi_rcv_egrbuftotlen = | ||
| 94 | pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size; | ||
| 95 | kinfo->spi_rcv_egrperchunk = pd->port_rcvegrbufs_perchunk; | ||
| 96 | kinfo->spi_rcv_egrchunksize = kinfo->spi_rcv_egrbuftotlen / | ||
| 97 | pd->port_rcvegrbuf_chunks; | ||
| 98 | kinfo->spi_tidcnt = dd->ipath_rcvtidcnt; | ||
| 99 | /* | ||
| 100 | * for this use, may be ipath_cfgports summed over all chips that | ||
| 101 | * are are configured and present | ||
| 102 | */ | ||
| 103 | kinfo->spi_nports = dd->ipath_cfgports; | ||
| 104 | /* unit (chip/board) our port is on */ | ||
| 105 | kinfo->spi_unit = dd->ipath_unit; | ||
| 106 | /* for now, only a single page */ | ||
| 107 | kinfo->spi_tid_maxsize = PAGE_SIZE; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Doing this per port, and based on the skip value, etc. This has | ||
| 111 | * to be the actual buffer size, since the protocol code treats it | ||
| 112 | * as an array. | ||
| 113 | * | ||
| 114 | * These have to be set to user addresses in the user code via mmap. | ||
| 115 | * These values are used on return to user code for the mmap target | ||
| 116 | * addresses only. For 32 bit, same 44 bit address problem, so use | ||
| 117 | * the physical address, not virtual. Before 2.6.11, using the | ||
| 118 | * page_address() macro worked, but in 2.6.11, even that returns the | ||
| 119 | * full 64 bit address (upper bits all 1's). So far, using the | ||
| 120 | * physical addresses (or chip offsets, for chip mapping) works, but | ||
| 121 | * no doubt some future kernel release will chang that, and we'll be | ||
| 122 | * on to yet another method of dealing with this | ||
| 123 | */ | ||
| 124 | kinfo->spi_rcvhdr_base = (u64) pd->port_rcvhdrq_phys; | ||
| 125 | kinfo->spi_rcv_egrbufs = (u64) pd->port_rcvegr_phys; | ||
| 126 | kinfo->spi_pioavailaddr = (u64) dd->ipath_pioavailregs_phys; | ||
| 127 | kinfo->spi_status = (u64) kinfo->spi_pioavailaddr + | ||
| 128 | (void *) dd->ipath_statusp - | ||
| 129 | (void *) dd->ipath_pioavailregs_dma; | ||
| 130 | kinfo->spi_piobufbase = (u64) pd->port_piobufs; | ||
| 131 | kinfo->__spi_uregbase = | ||
| 132 | dd->ipath_uregbase + dd->ipath_palign * pd->port_port; | ||
| 133 | |||
| 134 | kinfo->spi_pioindex = dd->ipath_pbufsport * (pd->port_port - 1); | ||
| 135 | kinfo->spi_piocnt = dd->ipath_pbufsport; | ||
| 136 | kinfo->spi_pioalign = dd->ipath_palign; | ||
| 137 | |||
| 138 | kinfo->spi_qpair = IPATH_KD_QP; | ||
| 139 | kinfo->spi_piosize = dd->ipath_ibmaxlen; | ||
| 140 | kinfo->spi_mtu = dd->ipath_ibmaxlen; /* maxlen, not ibmtu */ | ||
| 141 | kinfo->spi_port = pd->port_port; | ||
| 142 | kinfo->spi_sw_version = IPATH_USER_SWVERSION; | ||
| 143 | kinfo->spi_hw_version = dd->ipath_revision; | ||
| 144 | |||
| 145 | if (copy_to_user(ubase, kinfo, sizeof(*kinfo))) | ||
| 146 | ret = -EFAULT; | ||
| 147 | |||
| 148 | bail: | ||
| 149 | kfree(kinfo); | ||
| 150 | return ret; | ||
| 151 | } | ||
| 152 | |||
| 153 | /** | ||
| 154 | * ipath_tid_update - update a port TID | ||
| 155 | * @pd: the port | ||
| 156 | * @ti: the TID information | ||
| 157 | * | ||
| 158 | * The new implementation as of Oct 2004 is that the driver assigns | ||
| 159 | * the tid and returns it to the caller. To make it easier to | ||
| 160 | * catch bugs, and to reduce search time, we keep a cursor for | ||
| 161 | * each port, walking the shadow tid array to find one that's not | ||
| 162 | * in use. | ||
| 163 | * | ||
| 164 | * For now, if we can't allocate the full list, we fail, although | ||
| 165 | * in the long run, we'll allocate as many as we can, and the | ||
| 166 | * caller will deal with that by trying the remaining pages later. | ||
| 167 | * That means that when we fail, we have to mark the tids as not in | ||
| 168 | * use again, in our shadow copy. | ||
| 169 | * | ||
| 170 | * It's up to the caller to free the tids when they are done. | ||
| 171 | * We'll unlock the pages as they free them. | ||
| 172 | * | ||
| 173 | * Also, right now we are locking one page at a time, but since | ||
| 174 | * the intended use of this routine is for a single group of | ||
| 175 | * virtually contiguous pages, that should change to improve | ||
| 176 | * performance. | ||
| 177 | */ | ||
| 178 | static int ipath_tid_update(struct ipath_portdata *pd, | ||
| 179 | const struct ipath_tid_info *ti) | ||
| 180 | { | ||
| 181 | int ret = 0, ntids; | ||
| 182 | u32 tid, porttid, cnt, i, tidcnt; | ||
| 183 | u16 *tidlist; | ||
| 184 | struct ipath_devdata *dd = pd->port_dd; | ||
| 185 | u64 physaddr; | ||
| 186 | unsigned long vaddr; | ||
| 187 | u64 __iomem *tidbase; | ||
| 188 | unsigned long tidmap[8]; | ||
| 189 | struct page **pagep = NULL; | ||
| 190 | |||
| 191 | if (!dd->ipath_pageshadow) { | ||
| 192 | ret = -ENOMEM; | ||
| 193 | goto done; | ||
| 194 | } | ||
| 195 | |||
| 196 | cnt = ti->tidcnt; | ||
| 197 | if (!cnt) { | ||
| 198 | ipath_dbg("After copyin, tidcnt 0, tidlist %llx\n", | ||
| 199 | (unsigned long long) ti->tidlist); | ||
| 200 | /* | ||
| 201 | * Should we treat as success? likely a bug | ||
| 202 | */ | ||
| 203 | ret = -EFAULT; | ||
| 204 | goto done; | ||
| 205 | } | ||
| 206 | tidcnt = dd->ipath_rcvtidcnt; | ||
| 207 | if (cnt >= tidcnt) { | ||
| 208 | /* make sure it all fits in port_tid_pg_list */ | ||
| 209 | dev_info(&dd->pcidev->dev, "Process tried to allocate %u " | ||
| 210 | "TIDs, only trying max (%u)\n", cnt, tidcnt); | ||
| 211 | cnt = tidcnt; | ||
| 212 | } | ||
| 213 | pagep = (struct page **)pd->port_tid_pg_list; | ||
| 214 | tidlist = (u16 *) (&pagep[cnt]); | ||
| 215 | |||
| 216 | memset(tidmap, 0, sizeof(tidmap)); | ||
| 217 | tid = pd->port_tidcursor; | ||
| 218 | /* before decrement; chip actual # */ | ||
| 219 | porttid = pd->port_port * tidcnt; | ||
| 220 | ntids = tidcnt; | ||
| 221 | tidbase = (u64 __iomem *) (((char __iomem *) dd->ipath_kregbase) + | ||
| 222 | dd->ipath_rcvtidbase + | ||
| 223 | porttid * sizeof(*tidbase)); | ||
| 224 | |||
| 225 | ipath_cdbg(VERBOSE, "Port%u %u tids, cursor %u, tidbase %p\n", | ||
| 226 | pd->port_port, cnt, tid, tidbase); | ||
| 227 | |||
| 228 | /* virtual address of first page in transfer */ | ||
| 229 | vaddr = ti->tidvaddr; | ||
| 230 | if (!access_ok(VERIFY_WRITE, (void __user *) vaddr, | ||
| 231 | cnt * PAGE_SIZE)) { | ||
| 232 | ipath_dbg("Fail vaddr %p, %u pages, !access_ok\n", | ||
| 233 | (void *)vaddr, cnt); | ||
| 234 | ret = -EFAULT; | ||
| 235 | goto done; | ||
| 236 | } | ||
| 237 | ret = ipath_get_user_pages(vaddr, cnt, pagep); | ||
| 238 | if (ret) { | ||
| 239 | if (ret == -EBUSY) { | ||
| 240 | ipath_dbg("Failed to lock addr %p, %u pages " | ||
| 241 | "(already locked)\n", | ||
| 242 | (void *) vaddr, cnt); | ||
| 243 | /* | ||
| 244 | * for now, continue, and see what happens but with | ||
| 245 | * the new implementation, this should never happen, | ||
| 246 | * unless perhaps the user has mpin'ed the pages | ||
| 247 | * themselves (something we need to test) | ||
| 248 | */ | ||
| 249 | ret = 0; | ||
| 250 | } else { | ||
| 251 | dev_info(&dd->pcidev->dev, | ||
| 252 | "Failed to lock addr %p, %u pages: " | ||
| 253 | "errno %d\n", (void *) vaddr, cnt, -ret); | ||
| 254 | goto done; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | for (i = 0; i < cnt; i++, vaddr += PAGE_SIZE) { | ||
| 258 | for (; ntids--; tid++) { | ||
| 259 | if (tid == tidcnt) | ||
| 260 | tid = 0; | ||
| 261 | if (!dd->ipath_pageshadow[porttid + tid]) | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | if (ntids < 0) { | ||
| 265 | /* | ||
| 266 | * oops, wrapped all the way through their TIDs, | ||
| 267 | * and didn't have enough free; see comments at | ||
| 268 | * start of routine | ||
| 269 | */ | ||
| 270 | ipath_dbg("Not enough free TIDs for %u pages " | ||
| 271 | "(index %d), failing\n", cnt, i); | ||
| 272 | i--; /* last tidlist[i] not filled in */ | ||
| 273 | ret = -ENOMEM; | ||
| 274 | break; | ||
| 275 | } | ||
| 276 | tidlist[i] = tid; | ||
| 277 | ipath_cdbg(VERBOSE, "Updating idx %u to TID %u, " | ||
| 278 | "vaddr %lx\n", i, tid, vaddr); | ||
| 279 | /* we "know" system pages and TID pages are same size */ | ||
| 280 | dd->ipath_pageshadow[porttid + tid] = pagep[i]; | ||
| 281 | /* | ||
| 282 | * don't need atomic or it's overhead | ||
| 283 | */ | ||
| 284 | __set_bit(tid, tidmap); | ||
| 285 | physaddr = page_to_phys(pagep[i]); | ||
| 286 | ipath_stats.sps_pagelocks++; | ||
| 287 | ipath_cdbg(VERBOSE, | ||
| 288 | "TID %u, vaddr %lx, physaddr %llx pgp %p\n", | ||
| 289 | tid, vaddr, (unsigned long long) physaddr, | ||
| 290 | pagep[i]); | ||
| 291 | dd->ipath_f_put_tid(dd, &tidbase[tid], 1, physaddr); | ||
| 292 | /* | ||
| 293 | * don't check this tid in ipath_portshadow, since we | ||
| 294 | * just filled it in; start with the next one. | ||
| 295 | */ | ||
| 296 | tid++; | ||
| 297 | } | ||
| 298 | |||
| 299 | if (ret) { | ||
| 300 | u32 limit; | ||
| 301 | cleanup: | ||
| 302 | /* jump here if copy out of updated info failed... */ | ||
| 303 | ipath_dbg("After failure (ret=%d), undo %d of %d entries\n", | ||
| 304 | -ret, i, cnt); | ||
| 305 | /* same code that's in ipath_free_tid() */ | ||
| 306 | limit = sizeof(tidmap) * BITS_PER_BYTE; | ||
| 307 | if (limit > tidcnt) | ||
| 308 | /* just in case size changes in future */ | ||
| 309 | limit = tidcnt; | ||
| 310 | tid = find_first_bit((const unsigned long *)tidmap, limit); | ||
| 311 | for (; tid < limit; tid++) { | ||
| 312 | if (!test_bit(tid, tidmap)) | ||
| 313 | continue; | ||
| 314 | if (dd->ipath_pageshadow[porttid + tid]) { | ||
| 315 | ipath_cdbg(VERBOSE, "Freeing TID %u\n", | ||
| 316 | tid); | ||
| 317 | dd->ipath_f_put_tid(dd, &tidbase[tid], 1, | ||
| 318 | dd->ipath_tidinvalid); | ||
| 319 | dd->ipath_pageshadow[porttid + tid] = NULL; | ||
| 320 | ipath_stats.sps_pageunlocks++; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | ipath_release_user_pages(pagep, cnt); | ||
| 324 | } else { | ||
| 325 | /* | ||
| 326 | * Copy the updated array, with ipath_tid's filled in, back | ||
| 327 | * to user. Since we did the copy in already, this "should | ||
| 328 | * never fail" If it does, we have to clean up... | ||
| 329 | */ | ||
| 330 | if (copy_to_user((void __user *) | ||
| 331 | (unsigned long) ti->tidlist, | ||
| 332 | tidlist, cnt * sizeof(*tidlist))) { | ||
| 333 | ret = -EFAULT; | ||
| 334 | goto cleanup; | ||
| 335 | } | ||
| 336 | if (copy_to_user((void __user *) (unsigned long) ti->tidmap, | ||
| 337 | tidmap, sizeof tidmap)) { | ||
| 338 | ret = -EFAULT; | ||
| 339 | goto cleanup; | ||
| 340 | } | ||
| 341 | if (tid == tidcnt) | ||
| 342 | tid = 0; | ||
| 343 | pd->port_tidcursor = tid; | ||
| 344 | } | ||
| 345 | |||
| 346 | done: | ||
| 347 | if (ret) | ||
| 348 | ipath_dbg("Failed to map %u TID pages, failing with %d\n", | ||
| 349 | ti->tidcnt, -ret); | ||
| 350 | return ret; | ||
| 351 | } | ||
| 352 | |||
| 353 | /** | ||
| 354 | * ipath_tid_free - free a port TID | ||
| 355 | * @pd: the port | ||
| 356 | * @ti: the TID info | ||
| 357 | * | ||
| 358 | * right now we are unlocking one page at a time, but since | ||
| 359 | * the intended use of this routine is for a single group of | ||
| 360 | * virtually contiguous pages, that should change to improve | ||
| 361 | * performance. We check that the TID is in range for this port | ||
| 362 | * but otherwise don't check validity; if user has an error and | ||
| 363 | * frees the wrong tid, it's only their own data that can thereby | ||
| 364 | * be corrupted. We do check that the TID was in use, for sanity | ||
| 365 | * We always use our idea of the saved address, not the address that | ||
| 366 | * they pass in to us. | ||
| 367 | */ | ||
| 368 | |||
| 369 | static int ipath_tid_free(struct ipath_portdata *pd, | ||
| 370 | const struct ipath_tid_info *ti) | ||
| 371 | { | ||
| 372 | int ret = 0; | ||
| 373 | u32 tid, porttid, cnt, limit, tidcnt; | ||
| 374 | struct ipath_devdata *dd = pd->port_dd; | ||
| 375 | u64 __iomem *tidbase; | ||
| 376 | unsigned long tidmap[8]; | ||
| 377 | |||
| 378 | if (!dd->ipath_pageshadow) { | ||
| 379 | ret = -ENOMEM; | ||
| 380 | goto done; | ||
| 381 | } | ||
| 382 | |||
| 383 | if (copy_from_user(tidmap, (void __user *)(unsigned long)ti->tidmap, | ||
| 384 | sizeof tidmap)) { | ||
| 385 | ret = -EFAULT; | ||
| 386 | goto done; | ||
| 387 | } | ||
| 388 | |||
| 389 | porttid = pd->port_port * dd->ipath_rcvtidcnt; | ||
| 390 | tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) + | ||
| 391 | dd->ipath_rcvtidbase + | ||
| 392 | porttid * sizeof(*tidbase)); | ||
| 393 | |||
| 394 | tidcnt = dd->ipath_rcvtidcnt; | ||
| 395 | limit = sizeof(tidmap) * BITS_PER_BYTE; | ||
| 396 | if (limit > tidcnt) | ||
| 397 | /* just in case size changes in future */ | ||
| 398 | limit = tidcnt; | ||
| 399 | tid = find_first_bit(tidmap, limit); | ||
| 400 | ipath_cdbg(VERBOSE, "Port%u free %u tids; first bit (max=%d) " | ||
| 401 | "set is %d, porttid %u\n", pd->port_port, ti->tidcnt, | ||
| 402 | limit, tid, porttid); | ||
| 403 | for (cnt = 0; tid < limit; tid++) { | ||
| 404 | /* | ||
| 405 | * small optimization; if we detect a run of 3 or so without | ||
| 406 | * any set, use find_first_bit again. That's mainly to | ||
| 407 | * accelerate the case where we wrapped, so we have some at | ||
| 408 | * the beginning, and some at the end, and a big gap | ||
| 409 | * in the middle. | ||
| 410 | */ | ||
| 411 | if (!test_bit(tid, tidmap)) | ||
| 412 | continue; | ||
| 413 | cnt++; | ||
| 414 | if (dd->ipath_pageshadow[porttid + tid]) { | ||
| 415 | ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", | ||
| 416 | pd->port_pid, tid); | ||
| 417 | dd->ipath_f_put_tid(dd, &tidbase[tid], 1, | ||
| 418 | dd->ipath_tidinvalid); | ||
| 419 | ipath_release_user_pages( | ||
| 420 | &dd->ipath_pageshadow[porttid + tid], 1); | ||
| 421 | dd->ipath_pageshadow[porttid + tid] = NULL; | ||
| 422 | ipath_stats.sps_pageunlocks++; | ||
| 423 | } else | ||
| 424 | ipath_dbg("Unused tid %u, ignoring\n", tid); | ||
| 425 | } | ||
| 426 | if (cnt != ti->tidcnt) | ||
| 427 | ipath_dbg("passed in tidcnt %d, only %d bits set in map\n", | ||
| 428 | ti->tidcnt, cnt); | ||
| 429 | done: | ||
| 430 | if (ret) | ||
| 431 | ipath_dbg("Failed to unmap %u TID pages, failing with %d\n", | ||
| 432 | ti->tidcnt, -ret); | ||
| 433 | return ret; | ||
| 434 | } | ||
| 435 | |||
| 436 | /** | ||
| 437 | * ipath_set_part_key - set a partition key | ||
| 438 | * @pd: the port | ||
| 439 | * @key: the key | ||
| 440 | * | ||
| 441 | * We can have up to 4 active at a time (other than the default, which is | ||
| 442 | * always allowed). This is somewhat tricky, since multiple ports may set | ||
| 443 | * the same key, so we reference count them, and clean up at exit. All 4 | ||
| 444 | * partition keys are packed into a single infinipath register. It's an | ||
| 445 | * error for a process to set the same pkey multiple times. We provide no | ||
| 446 | * mechanism to de-allocate a pkey at this time, we may eventually need to | ||
| 447 | * do that. I've used the atomic operations, and no locking, and only make | ||
| 448 | * a single pass through what's available. This should be more than | ||
| 449 | * adequate for some time. I'll think about spinlocks or the like if and as | ||
| 450 | * it's necessary. | ||
| 451 | */ | ||
| 452 | static int ipath_set_part_key(struct ipath_portdata *pd, u16 key) | ||
| 453 | { | ||
| 454 | struct ipath_devdata *dd = pd->port_dd; | ||
| 455 | int i, any = 0, pidx = -1; | ||
| 456 | u16 lkey = key & 0x7FFF; | ||
| 457 | int ret; | ||
| 458 | |||
| 459 | if (lkey == (IPS_DEFAULT_P_KEY & 0x7FFF)) { | ||
| 460 | /* nothing to do; this key always valid */ | ||
| 461 | ret = 0; | ||
| 462 | goto bail; | ||
| 463 | } | ||
| 464 | |||
| 465 | ipath_cdbg(VERBOSE, "p%u try to set pkey %hx, current keys " | ||
| 466 | "%hx:%x %hx:%x %hx:%x %hx:%x\n", | ||
| 467 | pd->port_port, key, dd->ipath_pkeys[0], | ||
| 468 | atomic_read(&dd->ipath_pkeyrefs[0]), dd->ipath_pkeys[1], | ||
| 469 | atomic_read(&dd->ipath_pkeyrefs[1]), dd->ipath_pkeys[2], | ||
| 470 | atomic_read(&dd->ipath_pkeyrefs[2]), dd->ipath_pkeys[3], | ||
| 471 | atomic_read(&dd->ipath_pkeyrefs[3])); | ||
| 472 | |||
| 473 | if (!lkey) { | ||
| 474 | ipath_cdbg(PROC, "p%u tries to set key 0, not allowed\n", | ||
| 475 | pd->port_port); | ||
| 476 | ret = -EINVAL; | ||
| 477 | goto bail; | ||
| 478 | } | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Set the full membership bit, because it has to be | ||
| 482 | * set in the register or the packet, and it seems | ||
| 483 | * cleaner to set in the register than to force all | ||
| 484 | * callers to set it. (see bug 4331) | ||
| 485 | */ | ||
| 486 | key |= 0x8000; | ||
| 487 | |||
| 488 | for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) { | ||
| 489 | if (!pd->port_pkeys[i] && pidx == -1) | ||
| 490 | pidx = i; | ||
| 491 | if (pd->port_pkeys[i] == key) { | ||
| 492 | ipath_cdbg(VERBOSE, "p%u tries to set same pkey " | ||
| 493 | "(%x) more than once\n", | ||
| 494 | pd->port_port, key); | ||
| 495 | ret = -EEXIST; | ||
| 496 | goto bail; | ||
| 497 | } | ||
| 498 | } | ||
| 499 | if (pidx == -1) { | ||
| 500 | ipath_dbg("All pkeys for port %u already in use, " | ||
| 501 | "can't set %x\n", pd->port_port, key); | ||
| 502 | ret = -EBUSY; | ||
| 503 | goto bail; | ||
| 504 | } | ||
| 505 | for (any = i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
| 506 | if (!dd->ipath_pkeys[i]) { | ||
| 507 | any++; | ||
| 508 | continue; | ||
| 509 | } | ||
| 510 | if (dd->ipath_pkeys[i] == key) { | ||
| 511 | atomic_t *pkrefs = &dd->ipath_pkeyrefs[i]; | ||
| 512 | |||
| 513 | if (atomic_inc_return(pkrefs) > 1) { | ||
| 514 | pd->port_pkeys[pidx] = key; | ||
| 515 | ipath_cdbg(VERBOSE, "p%u set key %x " | ||
| 516 | "matches #%d, count now %d\n", | ||
| 517 | pd->port_port, key, i, | ||
| 518 | atomic_read(pkrefs)); | ||
| 519 | ret = 0; | ||
| 520 | goto bail; | ||
| 521 | } else { | ||
| 522 | /* | ||
| 523 | * lost race, decrement count, catch below | ||
| 524 | */ | ||
| 525 | atomic_dec(pkrefs); | ||
| 526 | ipath_cdbg(VERBOSE, "Lost race, count was " | ||
| 527 | "0, after dec, it's %d\n", | ||
| 528 | atomic_read(pkrefs)); | ||
| 529 | any++; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) { | ||
| 533 | /* | ||
| 534 | * It makes no sense to have both the limited and | ||
| 535 | * full membership PKEY set at the same time since | ||
| 536 | * the unlimited one will disable the limited one. | ||
| 537 | */ | ||
| 538 | ret = -EEXIST; | ||
| 539 | goto bail; | ||
| 540 | } | ||
| 541 | } | ||
| 542 | if (!any) { | ||
| 543 | ipath_dbg("port %u, all pkeys already in use, " | ||
| 544 | "can't set %x\n", pd->port_port, key); | ||
| 545 | ret = -EBUSY; | ||
| 546 | goto bail; | ||
| 547 | } | ||
| 548 | for (any = i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
| 549 | if (!dd->ipath_pkeys[i] && | ||
| 550 | atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) { | ||
| 551 | u64 pkey; | ||
| 552 | |||
| 553 | /* for ipathstats, etc. */ | ||
| 554 | ipath_stats.sps_pkeys[i] = lkey; | ||
| 555 | pd->port_pkeys[pidx] = dd->ipath_pkeys[i] = key; | ||
| 556 | pkey = | ||
| 557 | (u64) dd->ipath_pkeys[0] | | ||
| 558 | ((u64) dd->ipath_pkeys[1] << 16) | | ||
| 559 | ((u64) dd->ipath_pkeys[2] << 32) | | ||
| 560 | ((u64) dd->ipath_pkeys[3] << 48); | ||
| 561 | ipath_cdbg(PROC, "p%u set key %x in #%d, " | ||
| 562 | "portidx %d, new pkey reg %llx\n", | ||
| 563 | pd->port_port, key, i, pidx, | ||
| 564 | (unsigned long long) pkey); | ||
| 565 | ipath_write_kreg( | ||
| 566 | dd, dd->ipath_kregs->kr_partitionkey, pkey); | ||
| 567 | |||
| 568 | ret = 0; | ||
| 569 | goto bail; | ||
| 570 | } | ||
| 571 | } | ||
| 572 | ipath_dbg("port %u, all pkeys already in use 2nd pass, " | ||
| 573 | "can't set %x\n", pd->port_port, key); | ||
| 574 | ret = -EBUSY; | ||
| 575 | |||
| 576 | bail: | ||
| 577 | return ret; | ||
| 578 | } | ||
| 579 | |||
| 580 | /** | ||
| 581 | * ipath_manage_rcvq - manage a port's receive queue | ||
| 582 | * @pd: the port | ||
| 583 | * @start_stop: action to carry out | ||
| 584 | * | ||
| 585 | * start_stop == 0 disables receive on the port, for use in queue | ||
| 586 | * overflow conditions. start_stop==1 re-enables, to be used to | ||
| 587 | * re-init the software copy of the head register | ||
| 588 | */ | ||
| 589 | static int ipath_manage_rcvq(struct ipath_portdata *pd, int start_stop) | ||
| 590 | { | ||
| 591 | struct ipath_devdata *dd = pd->port_dd; | ||
| 592 | u64 tval; | ||
| 593 | |||
| 594 | ipath_cdbg(PROC, "%sabling rcv for unit %u port %u\n", | ||
| 595 | start_stop ? "en" : "dis", dd->ipath_unit, | ||
| 596 | pd->port_port); | ||
| 597 | /* atomically clear receive enable port. */ | ||
| 598 | if (start_stop) { | ||
| 599 | /* | ||
| 600 | * On enable, force in-memory copy of the tail register to | ||
| 601 | * 0, so that protocol code doesn't have to worry about | ||
| 602 | * whether or not the chip has yet updated the in-memory | ||
| 603 | * copy or not on return from the system call. The chip | ||
| 604 | * always resets it's tail register back to 0 on a | ||
| 605 | * transition from disabled to enabled. This could cause a | ||
| 606 | * problem if software was broken, and did the enable w/o | ||
| 607 | * the disable, but eventually the in-memory copy will be | ||
| 608 | * updated and correct itself, even in the face of software | ||
| 609 | * bugs. | ||
| 610 | */ | ||
| 611 | *pd->port_rcvhdrtail_kvaddr = 0; | ||
| 612 | set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | ||
| 613 | &dd->ipath_rcvctrl); | ||
| 614 | } else | ||
| 615 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | ||
| 616 | &dd->ipath_rcvctrl); | ||
| 617 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 618 | dd->ipath_rcvctrl); | ||
| 619 | /* now be sure chip saw it before we return */ | ||
| 620 | tval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 621 | if (start_stop) { | ||
| 622 | /* | ||
| 623 | * And try to be sure that tail reg update has happened too. | ||
| 624 | * This should in theory interlock with the RXE changes to | ||
| 625 | * the tail register. Don't assign it to the tail register | ||
| 626 | * in memory copy, since we could overwrite an update by the | ||
| 627 | * chip if we did. | ||
| 628 | */ | ||
| 629 | tval = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port); | ||
| 630 | } | ||
| 631 | /* always; new head should be equal to new tail; see above */ | ||
| 632 | return 0; | ||
| 633 | } | ||
| 634 | |||
| 635 | static void ipath_clean_part_key(struct ipath_portdata *pd, | ||
| 636 | struct ipath_devdata *dd) | ||
| 637 | { | ||
| 638 | int i, j, pchanged = 0; | ||
| 639 | u64 oldpkey; | ||
| 640 | |||
| 641 | /* for debugging only */ | ||
| 642 | oldpkey = (u64) dd->ipath_pkeys[0] | | ||
| 643 | ((u64) dd->ipath_pkeys[1] << 16) | | ||
| 644 | ((u64) dd->ipath_pkeys[2] << 32) | | ||
| 645 | ((u64) dd->ipath_pkeys[3] << 48); | ||
| 646 | |||
| 647 | for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) { | ||
| 648 | if (!pd->port_pkeys[i]) | ||
| 649 | continue; | ||
| 650 | ipath_cdbg(VERBOSE, "look for key[%d] %hx in pkeys\n", i, | ||
| 651 | pd->port_pkeys[i]); | ||
| 652 | for (j = 0; j < ARRAY_SIZE(dd->ipath_pkeys); j++) { | ||
| 653 | /* check for match independent of the global bit */ | ||
| 654 | if ((dd->ipath_pkeys[j] & 0x7fff) != | ||
| 655 | (pd->port_pkeys[i] & 0x7fff)) | ||
| 656 | continue; | ||
| 657 | if (atomic_dec_and_test(&dd->ipath_pkeyrefs[j])) { | ||
| 658 | ipath_cdbg(VERBOSE, "p%u clear key " | ||
| 659 | "%x matches #%d\n", | ||
| 660 | pd->port_port, | ||
| 661 | pd->port_pkeys[i], j); | ||
| 662 | ipath_stats.sps_pkeys[j] = | ||
| 663 | dd->ipath_pkeys[j] = 0; | ||
| 664 | pchanged++; | ||
| 665 | } | ||
| 666 | else ipath_cdbg( | ||
| 667 | VERBOSE, "p%u key %x matches #%d, " | ||
| 668 | "but ref still %d\n", pd->port_port, | ||
| 669 | pd->port_pkeys[i], j, | ||
| 670 | atomic_read(&dd->ipath_pkeyrefs[j])); | ||
| 671 | break; | ||
| 672 | } | ||
| 673 | pd->port_pkeys[i] = 0; | ||
| 674 | } | ||
| 675 | if (pchanged) { | ||
| 676 | u64 pkey = (u64) dd->ipath_pkeys[0] | | ||
| 677 | ((u64) dd->ipath_pkeys[1] << 16) | | ||
| 678 | ((u64) dd->ipath_pkeys[2] << 32) | | ||
| 679 | ((u64) dd->ipath_pkeys[3] << 48); | ||
| 680 | ipath_cdbg(VERBOSE, "p%u old pkey reg %llx, " | ||
| 681 | "new pkey reg %llx\n", pd->port_port, | ||
| 682 | (unsigned long long) oldpkey, | ||
| 683 | (unsigned long long) pkey); | ||
| 684 | ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey, | ||
| 685 | pkey); | ||
| 686 | } | ||
| 687 | } | ||
| 688 | |||
| 689 | /** | ||
| 690 | * ipath_create_user_egr - allocate eager TID buffers | ||
| 691 | * @pd: the port to allocate TID buffers for | ||
| 692 | * | ||
| 693 | * This routine is now quite different for user and kernel, because | ||
| 694 | * the kernel uses skb's, for the accelerated network performance | ||
| 695 | * This is the user port version | ||
| 696 | * | ||
| 697 | * Allocate the eager TID buffers and program them into infinipath | ||
| 698 | * They are no longer completely contiguous, we do multiple allocation | ||
| 699 | * calls. | ||
| 700 | */ | ||
| 701 | static int ipath_create_user_egr(struct ipath_portdata *pd) | ||
| 702 | { | ||
| 703 | struct ipath_devdata *dd = pd->port_dd; | ||
| 704 | unsigned e, egrcnt, alloced, egrperchunk, chunk, egrsize, egroff; | ||
| 705 | size_t size; | ||
| 706 | int ret; | ||
| 707 | |||
| 708 | egrcnt = dd->ipath_rcvegrcnt; | ||
| 709 | /* TID number offset for this port */ | ||
| 710 | egroff = pd->port_port * egrcnt; | ||
| 711 | egrsize = dd->ipath_rcvegrbufsize; | ||
| 712 | ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid " | ||
| 713 | "offset %x, egrsize %u\n", egrcnt, egroff, egrsize); | ||
| 714 | |||
| 715 | /* | ||
| 716 | * to avoid wasting a lot of memory, we allocate 32KB chunks of | ||
| 717 | * physically contiguous memory, advance through it until used up | ||
| 718 | * and then allocate more. Of course, we need memory to store those | ||
| 719 | * extra pointers, now. Started out with 256KB, but under heavy | ||
| 720 | * memory pressure (creating large files and then copying them over | ||
| 721 | * NFS while doing lots of MPI jobs), we hit some allocation | ||
| 722 | * failures, even though we can sleep... (2.6.10) Still get | ||
| 723 | * failures at 64K. 32K is the lowest we can go without waiting | ||
| 724 | * more memory again. It seems likely that the coalescing in | ||
| 725 | * free_pages, etc. still has issues (as it has had previously | ||
| 726 | * during 2.6.x development). | ||
| 727 | */ | ||
| 728 | size = 0x8000; | ||
| 729 | alloced = ALIGN(egrsize * egrcnt, size); | ||
| 730 | egrperchunk = size / egrsize; | ||
| 731 | chunk = (egrcnt + egrperchunk - 1) / egrperchunk; | ||
| 732 | pd->port_rcvegrbuf_chunks = chunk; | ||
| 733 | pd->port_rcvegrbufs_perchunk = egrperchunk; | ||
| 734 | pd->port_rcvegrbuf_size = size; | ||
| 735 | pd->port_rcvegrbuf = vmalloc(chunk * sizeof(pd->port_rcvegrbuf[0])); | ||
| 736 | if (!pd->port_rcvegrbuf) { | ||
| 737 | ret = -ENOMEM; | ||
| 738 | goto bail; | ||
| 739 | } | ||
| 740 | pd->port_rcvegrbuf_phys = | ||
| 741 | vmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0])); | ||
| 742 | if (!pd->port_rcvegrbuf_phys) { | ||
| 743 | ret = -ENOMEM; | ||
| 744 | goto bail_rcvegrbuf; | ||
| 745 | } | ||
| 746 | for (e = 0; e < pd->port_rcvegrbuf_chunks; e++) { | ||
| 747 | /* | ||
| 748 | * GFP_USER, but without GFP_FS, so buffer cache can be | ||
| 749 | * coalesced (we hope); otherwise, even at order 4, | ||
| 750 | * heavy filesystem activity makes these fail | ||
| 751 | */ | ||
| 752 | gfp_t gfp_flags = __GFP_WAIT | __GFP_IO | __GFP_COMP; | ||
| 753 | |||
| 754 | pd->port_rcvegrbuf[e] = dma_alloc_coherent( | ||
| 755 | &dd->pcidev->dev, size, &pd->port_rcvegrbuf_phys[e], | ||
| 756 | gfp_flags); | ||
| 757 | |||
| 758 | if (!pd->port_rcvegrbuf[e]) { | ||
| 759 | ret = -ENOMEM; | ||
| 760 | goto bail_rcvegrbuf_phys; | ||
| 761 | } | ||
| 762 | } | ||
| 763 | |||
| 764 | pd->port_rcvegr_phys = pd->port_rcvegrbuf_phys[0]; | ||
| 765 | |||
| 766 | for (e = chunk = 0; chunk < pd->port_rcvegrbuf_chunks; chunk++) { | ||
| 767 | dma_addr_t pa = pd->port_rcvegrbuf_phys[chunk]; | ||
| 768 | unsigned i; | ||
| 769 | |||
| 770 | for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) { | ||
| 771 | dd->ipath_f_put_tid(dd, e + egroff + | ||
| 772 | (u64 __iomem *) | ||
| 773 | ((char __iomem *) | ||
| 774 | dd->ipath_kregbase + | ||
| 775 | dd->ipath_rcvegrbase), 0, pa); | ||
| 776 | pa += egrsize; | ||
| 777 | } | ||
| 778 | cond_resched(); /* don't hog the cpu */ | ||
| 779 | } | ||
| 780 | |||
| 781 | ret = 0; | ||
| 782 | goto bail; | ||
| 783 | |||
| 784 | bail_rcvegrbuf_phys: | ||
| 785 | for (e = 0; e < pd->port_rcvegrbuf_chunks && | ||
| 786 | pd->port_rcvegrbuf[e]; e++) | ||
| 787 | dma_free_coherent(&dd->pcidev->dev, size, | ||
| 788 | pd->port_rcvegrbuf[e], | ||
| 789 | pd->port_rcvegrbuf_phys[e]); | ||
| 790 | |||
| 791 | vfree(pd->port_rcvegrbuf_phys); | ||
| 792 | pd->port_rcvegrbuf_phys = NULL; | ||
| 793 | bail_rcvegrbuf: | ||
| 794 | vfree(pd->port_rcvegrbuf); | ||
| 795 | pd->port_rcvegrbuf = NULL; | ||
| 796 | bail: | ||
| 797 | return ret; | ||
| 798 | } | ||
| 799 | |||
| 800 | static int ipath_do_user_init(struct ipath_portdata *pd, | ||
| 801 | const struct ipath_user_info *uinfo) | ||
| 802 | { | ||
| 803 | int ret = 0; | ||
| 804 | struct ipath_devdata *dd = pd->port_dd; | ||
| 805 | u64 physaddr, uaddr, off, atmp; | ||
| 806 | struct page *pagep; | ||
| 807 | u32 head32; | ||
| 808 | u64 head; | ||
| 809 | |||
| 810 | /* for now, if major version is different, bail */ | ||
| 811 | if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) { | ||
| 812 | dev_info(&dd->pcidev->dev, | ||
| 813 | "User major version %d not same as driver " | ||
| 814 | "major %d\n", uinfo->spu_userversion >> 16, | ||
| 815 | IPATH_USER_SWMAJOR); | ||
| 816 | ret = -ENODEV; | ||
| 817 | goto done; | ||
| 818 | } | ||
| 819 | |||
| 820 | if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR) | ||
| 821 | ipath_dbg("User minor version %d not same as driver " | ||
| 822 | "minor %d\n", uinfo->spu_userversion & 0xffff, | ||
| 823 | IPATH_USER_SWMINOR); | ||
| 824 | |||
| 825 | if (uinfo->spu_rcvhdrsize) { | ||
| 826 | ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize); | ||
| 827 | if (ret) | ||
| 828 | goto done; | ||
| 829 | } | ||
| 830 | |||
| 831 | /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */ | ||
| 832 | |||
| 833 | /* set up for the rcvhdr Q tail register writeback to user memory */ | ||
| 834 | if (!uinfo->spu_rcvhdraddr || | ||
| 835 | !access_ok(VERIFY_WRITE, (u64 __user *) (unsigned long) | ||
| 836 | uinfo->spu_rcvhdraddr, sizeof(u64))) { | ||
| 837 | ipath_dbg("Port %d rcvhdrtail addr %llx not valid\n", | ||
| 838 | pd->port_port, | ||
| 839 | (unsigned long long) uinfo->spu_rcvhdraddr); | ||
| 840 | ret = -EINVAL; | ||
| 841 | goto done; | ||
| 842 | } | ||
| 843 | |||
| 844 | off = offset_in_page(uinfo->spu_rcvhdraddr); | ||
| 845 | uaddr = PAGE_MASK & (unsigned long) uinfo->spu_rcvhdraddr; | ||
| 846 | ret = ipath_get_user_pages_nocopy(uaddr, &pagep); | ||
| 847 | if (ret) { | ||
| 848 | dev_info(&dd->pcidev->dev, "Failed to lookup and lock " | ||
| 849 | "address %llx for rcvhdrtail: errno %d\n", | ||
| 850 | (unsigned long long) uinfo->spu_rcvhdraddr, -ret); | ||
| 851 | goto done; | ||
| 852 | } | ||
| 853 | ipath_stats.sps_pagelocks++; | ||
| 854 | pd->port_rcvhdrtail_uaddr = uaddr; | ||
| 855 | pd->port_rcvhdrtail_pagep = pagep; | ||
| 856 | pd->port_rcvhdrtail_kvaddr = | ||
| 857 | page_address(pagep); | ||
| 858 | pd->port_rcvhdrtail_kvaddr += off; | ||
| 859 | physaddr = page_to_phys(pagep) + off; | ||
| 860 | ipath_cdbg(VERBOSE, "port %d user addr %llx hdrtailaddr, %llx " | ||
| 861 | "physical (off=%llx)\n", | ||
| 862 | pd->port_port, | ||
| 863 | (unsigned long long) uinfo->spu_rcvhdraddr, | ||
| 864 | (unsigned long long) physaddr, (unsigned long long) off); | ||
| 865 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdrtailaddr, | ||
| 866 | pd->port_port, physaddr); | ||
| 867 | atmp = ipath_read_kreg64_port(dd, | ||
| 868 | dd->ipath_kregs->kr_rcvhdrtailaddr, | ||
| 869 | pd->port_port); | ||
| 870 | if (physaddr != atmp) { | ||
| 871 | ipath_dev_err(dd, | ||
| 872 | "Catastrophic software error, " | ||
| 873 | "RcvHdrTailAddr%u written as %llx, " | ||
| 874 | "read back as %llx\n", pd->port_port, | ||
| 875 | (unsigned long long) physaddr, | ||
| 876 | (unsigned long long) atmp); | ||
| 877 | ret = -EINVAL; | ||
| 878 | goto done; | ||
| 879 | } | ||
| 880 | |||
| 881 | /* for right now, kernel piobufs are at end, so port 1 is at 0 */ | ||
| 882 | pd->port_piobufs = dd->ipath_piobufbase + | ||
| 883 | dd->ipath_pbufsport * (pd->port_port - | ||
| 884 | 1) * dd->ipath_palign; | ||
| 885 | ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n", | ||
| 886 | pd->port_port, pd->port_piobufs); | ||
| 887 | |||
| 888 | /* | ||
| 889 | * Now allocate the rcvhdr Q and eager TIDs; skip the TID | ||
| 890 | * array for time being. If pd->port_port > chip-supported, | ||
| 891 | * we need to do extra stuff here to handle by handling overflow | ||
| 892 | * through port 0, someday | ||
| 893 | */ | ||
| 894 | ret = ipath_create_rcvhdrq(dd, pd); | ||
| 895 | if (!ret) | ||
| 896 | ret = ipath_create_user_egr(pd); | ||
| 897 | if (ret) | ||
| 898 | goto done; | ||
| 899 | /* enable receives now */ | ||
| 900 | /* atomically set enable bit for this port */ | ||
| 901 | set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | ||
| 902 | &dd->ipath_rcvctrl); | ||
| 903 | |||
| 904 | /* | ||
| 905 | * set the head registers for this port to the current values | ||
| 906 | * of the tail pointers, since we don't know if they were | ||
| 907 | * updated on last use of the port. | ||
| 908 | */ | ||
| 909 | head32 = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port); | ||
| 910 | head = (u64) head32; | ||
| 911 | ipath_write_ureg(dd, ur_rcvhdrhead, head, pd->port_port); | ||
| 912 | head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port); | ||
| 913 | ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port); | ||
| 914 | dd->ipath_lastegrheads[pd->port_port] = -1; | ||
| 915 | dd->ipath_lastrcvhdrqtails[pd->port_port] = -1; | ||
| 916 | ipath_cdbg(VERBOSE, "Wrote port%d head %llx, egrhead %x from " | ||
| 917 | "tail regs\n", pd->port_port, | ||
| 918 | (unsigned long long) head, head32); | ||
| 919 | pd->port_tidcursor = 0; /* start at beginning after open */ | ||
| 920 | /* | ||
| 921 | * now enable the port; the tail registers will be written to memory | ||
| 922 | * by the chip as soon as it sees the write to | ||
| 923 | * dd->ipath_kregs->kr_rcvctrl. The update only happens on | ||
| 924 | * transition from 0 to 1, so clear it first, then set it as part of | ||
| 925 | * enabling the port. This will (very briefly) affect any other | ||
| 926 | * open ports, but it shouldn't be long enough to be an issue. | ||
| 927 | */ | ||
| 928 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 929 | dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD); | ||
| 930 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 931 | dd->ipath_rcvctrl); | ||
| 932 | |||
| 933 | done: | ||
| 934 | return ret; | ||
| 935 | } | ||
| 936 | |||
| 937 | static int mmap_ureg(struct vm_area_struct *vma, struct ipath_devdata *dd, | ||
| 938 | u64 ureg) | ||
| 939 | { | ||
| 940 | unsigned long phys; | ||
| 941 | int ret; | ||
| 942 | |||
| 943 | /* it's the real hardware, so io_remap works */ | ||
| 944 | |||
| 945 | if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) { | ||
| 946 | dev_info(&dd->pcidev->dev, "FAIL mmap userreg: reqlen " | ||
| 947 | "%lx > PAGE\n", vma->vm_end - vma->vm_start); | ||
| 948 | ret = -EFAULT; | ||
| 949 | } else { | ||
| 950 | phys = dd->ipath_physaddr + ureg; | ||
| 951 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 952 | |||
| 953 | vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; | ||
| 954 | ret = io_remap_pfn_range(vma, vma->vm_start, | ||
| 955 | phys >> PAGE_SHIFT, | ||
| 956 | vma->vm_end - vma->vm_start, | ||
| 957 | vma->vm_page_prot); | ||
| 958 | } | ||
| 959 | return ret; | ||
| 960 | } | ||
| 961 | |||
| 962 | static int mmap_piobufs(struct vm_area_struct *vma, | ||
| 963 | struct ipath_devdata *dd, | ||
| 964 | struct ipath_portdata *pd) | ||
| 965 | { | ||
| 966 | unsigned long phys; | ||
| 967 | int ret; | ||
| 968 | |||
| 969 | /* | ||
| 970 | * When we map the PIO buffers, we want to map them as writeonly, no | ||
| 971 | * read possible. | ||
| 972 | */ | ||
| 973 | |||
| 974 | if ((vma->vm_end - vma->vm_start) > | ||
| 975 | (dd->ipath_pbufsport * dd->ipath_palign)) { | ||
| 976 | dev_info(&dd->pcidev->dev, "FAIL mmap piobufs: " | ||
| 977 | "reqlen %lx > PAGE\n", | ||
| 978 | vma->vm_end - vma->vm_start); | ||
| 979 | ret = -EFAULT; | ||
| 980 | goto bail; | ||
| 981 | } | ||
| 982 | |||
| 983 | phys = dd->ipath_physaddr + pd->port_piobufs; | ||
| 984 | /* | ||
| 985 | * Do *NOT* mark this as non-cached (PWT bit), or we don't get the | ||
| 986 | * write combining behavior we want on the PIO buffers! | ||
| 987 | * vma->vm_page_prot = | ||
| 988 | * pgprot_noncached(vma->vm_page_prot); | ||
| 989 | */ | ||
| 990 | |||
| 991 | if (vma->vm_flags & VM_READ) { | ||
| 992 | dev_info(&dd->pcidev->dev, | ||
| 993 | "Can't map piobufs as readable (flags=%lx)\n", | ||
| 994 | vma->vm_flags); | ||
| 995 | ret = -EPERM; | ||
| 996 | goto bail; | ||
| 997 | } | ||
| 998 | |||
| 999 | /* don't allow them to later change to readable with mprotect */ | ||
| 1000 | |||
| 1001 | vma->vm_flags &= ~VM_MAYWRITE; | ||
| 1002 | vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; | ||
| 1003 | |||
| 1004 | ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, | ||
| 1005 | vma->vm_end - vma->vm_start, | ||
| 1006 | vma->vm_page_prot); | ||
| 1007 | bail: | ||
| 1008 | return ret; | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | static int mmap_rcvegrbufs(struct vm_area_struct *vma, | ||
| 1012 | struct ipath_portdata *pd) | ||
| 1013 | { | ||
| 1014 | struct ipath_devdata *dd = pd->port_dd; | ||
| 1015 | unsigned long start, size; | ||
| 1016 | size_t total_size, i; | ||
| 1017 | dma_addr_t *phys; | ||
| 1018 | int ret; | ||
| 1019 | |||
| 1020 | if (!pd->port_rcvegrbuf) { | ||
| 1021 | ret = -EFAULT; | ||
| 1022 | goto bail; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | size = pd->port_rcvegrbuf_size; | ||
| 1026 | total_size = pd->port_rcvegrbuf_chunks * size; | ||
| 1027 | if ((vma->vm_end - vma->vm_start) > total_size) { | ||
| 1028 | dev_info(&dd->pcidev->dev, "FAIL on egr bufs: " | ||
| 1029 | "reqlen %lx > actual %lx\n", | ||
| 1030 | vma->vm_end - vma->vm_start, | ||
| 1031 | (unsigned long) total_size); | ||
| 1032 | ret = -EFAULT; | ||
| 1033 | goto bail; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | if (vma->vm_flags & VM_WRITE) { | ||
| 1037 | dev_info(&dd->pcidev->dev, "Can't map eager buffers as " | ||
| 1038 | "writable (flags=%lx)\n", vma->vm_flags); | ||
| 1039 | ret = -EPERM; | ||
| 1040 | goto bail; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | start = vma->vm_start; | ||
| 1044 | phys = pd->port_rcvegrbuf_phys; | ||
| 1045 | |||
| 1046 | /* don't allow them to later change to writeable with mprotect */ | ||
| 1047 | vma->vm_flags &= ~VM_MAYWRITE; | ||
| 1048 | |||
| 1049 | for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) { | ||
| 1050 | ret = remap_pfn_range(vma, start, phys[i] >> PAGE_SHIFT, | ||
| 1051 | size, vma->vm_page_prot); | ||
| 1052 | if (ret < 0) | ||
| 1053 | goto bail; | ||
| 1054 | } | ||
| 1055 | ret = 0; | ||
| 1056 | |||
| 1057 | bail: | ||
| 1058 | return ret; | ||
| 1059 | } | ||
| 1060 | |||
| 1061 | static int mmap_rcvhdrq(struct vm_area_struct *vma, | ||
| 1062 | struct ipath_portdata *pd) | ||
| 1063 | { | ||
| 1064 | struct ipath_devdata *dd = pd->port_dd; | ||
| 1065 | size_t total_size; | ||
| 1066 | int ret; | ||
| 1067 | |||
| 1068 | /* | ||
| 1069 | * kmalloc'ed memory, physically contiguous; this is from | ||
| 1070 | * spi_rcvhdr_base; we allow user to map read-write so they can | ||
| 1071 | * write hdrq entries to allow protocol code to directly poll | ||
| 1072 | * whether a hdrq entry has been written. | ||
| 1073 | */ | ||
| 1074 | total_size = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize * | ||
| 1075 | sizeof(u32), PAGE_SIZE); | ||
| 1076 | if ((vma->vm_end - vma->vm_start) > total_size) { | ||
| 1077 | dev_info(&dd->pcidev->dev, | ||
| 1078 | "FAIL on rcvhdrq: reqlen %lx > actual %lx\n", | ||
| 1079 | vma->vm_end - vma->vm_start, | ||
| 1080 | (unsigned long) total_size); | ||
| 1081 | ret = -EFAULT; | ||
| 1082 | goto bail; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | ret = remap_pfn_range(vma, vma->vm_start, | ||
| 1086 | pd->port_rcvhdrq_phys >> PAGE_SHIFT, | ||
| 1087 | vma->vm_end - vma->vm_start, | ||
| 1088 | vma->vm_page_prot); | ||
| 1089 | bail: | ||
| 1090 | return ret; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | static int mmap_pioavailregs(struct vm_area_struct *vma, | ||
| 1094 | struct ipath_portdata *pd) | ||
| 1095 | { | ||
| 1096 | struct ipath_devdata *dd = pd->port_dd; | ||
| 1097 | int ret; | ||
| 1098 | |||
| 1099 | /* | ||
| 1100 | * when we map the PIO bufferavail registers, we want to map them as | ||
| 1101 | * readonly, no write possible. | ||
| 1102 | * | ||
| 1103 | * kmalloc'ed memory, physically contiguous, one page only, readonly | ||
| 1104 | */ | ||
| 1105 | |||
| 1106 | if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) { | ||
| 1107 | dev_info(&dd->pcidev->dev, "FAIL on pioavailregs_dma: " | ||
| 1108 | "reqlen %lx > actual %lx\n", | ||
| 1109 | vma->vm_end - vma->vm_start, | ||
| 1110 | (unsigned long) PAGE_SIZE); | ||
| 1111 | ret = -EFAULT; | ||
| 1112 | goto bail; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | if (vma->vm_flags & VM_WRITE) { | ||
| 1116 | dev_info(&dd->pcidev->dev, | ||
| 1117 | "Can't map pioavailregs as writable (flags=%lx)\n", | ||
| 1118 | vma->vm_flags); | ||
| 1119 | ret = -EPERM; | ||
| 1120 | goto bail; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | /* don't allow them to later change with mprotect */ | ||
| 1124 | vma->vm_flags &= ~VM_MAYWRITE; | ||
| 1125 | |||
| 1126 | ret = remap_pfn_range(vma, vma->vm_start, | ||
| 1127 | dd->ipath_pioavailregs_phys >> PAGE_SHIFT, | ||
| 1128 | PAGE_SIZE, vma->vm_page_prot); | ||
| 1129 | bail: | ||
| 1130 | return ret; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | /** | ||
| 1134 | * ipath_mmap - mmap various structures into user space | ||
| 1135 | * @fp: the file pointer | ||
| 1136 | * @vma: the VM area | ||
| 1137 | * | ||
| 1138 | * We use this to have a shared buffer between the kernel and the user code | ||
| 1139 | * for the rcvhdr queue, egr buffers, and the per-port user regs and pio | ||
| 1140 | * buffers in the chip. We have the open and close entries so we can bump | ||
| 1141 | * the ref count and keep the driver from being unloaded while still mapped. | ||
| 1142 | */ | ||
| 1143 | static int ipath_mmap(struct file *fp, struct vm_area_struct *vma) | ||
| 1144 | { | ||
| 1145 | struct ipath_portdata *pd; | ||
| 1146 | struct ipath_devdata *dd; | ||
| 1147 | u64 pgaddr, ureg; | ||
| 1148 | int ret; | ||
| 1149 | |||
| 1150 | pd = port_fp(fp); | ||
| 1151 | dd = pd->port_dd; | ||
| 1152 | /* | ||
| 1153 | * This is the ipath_do_user_init() code, mapping the shared buffers | ||
| 1154 | * into the user process. The address referred to by vm_pgoff is the | ||
| 1155 | * virtual, not physical, address; we only do one mmap for each | ||
| 1156 | * space mapped. | ||
| 1157 | */ | ||
| 1158 | pgaddr = vma->vm_pgoff << PAGE_SHIFT; | ||
| 1159 | |||
| 1160 | /* | ||
| 1161 | * note that ureg does *NOT* have the kregvirt as part of it, to be | ||
| 1162 | * sure that for 32 bit programs, we don't end up trying to map a > | ||
| 1163 | * 44 address. Has to match ipath_get_base_info() code that sets | ||
| 1164 | * __spi_uregbase | ||
| 1165 | */ | ||
| 1166 | |||
| 1167 | ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port; | ||
| 1168 | |||
| 1169 | ipath_cdbg(MM, "ushare: pgaddr %llx vm_start=%lx, vmlen %lx\n", | ||
| 1170 | (unsigned long long) pgaddr, vma->vm_start, | ||
| 1171 | vma->vm_end - vma->vm_start); | ||
| 1172 | |||
| 1173 | if (pgaddr == ureg) | ||
| 1174 | ret = mmap_ureg(vma, dd, ureg); | ||
| 1175 | else if (pgaddr == pd->port_piobufs) | ||
| 1176 | ret = mmap_piobufs(vma, dd, pd); | ||
| 1177 | else if (pgaddr == (u64) pd->port_rcvegr_phys) | ||
| 1178 | ret = mmap_rcvegrbufs(vma, pd); | ||
| 1179 | else if (pgaddr == (u64) pd->port_rcvhdrq_phys) | ||
| 1180 | ret = mmap_rcvhdrq(vma, pd); | ||
| 1181 | else if (pgaddr == dd->ipath_pioavailregs_phys) | ||
| 1182 | ret = mmap_pioavailregs(vma, pd); | ||
| 1183 | else | ||
| 1184 | ret = -EINVAL; | ||
| 1185 | |||
| 1186 | vma->vm_private_data = NULL; | ||
| 1187 | |||
| 1188 | if (ret < 0) | ||
| 1189 | dev_info(&dd->pcidev->dev, | ||
| 1190 | "Failure %d on addr %lx, off %lx\n", | ||
| 1191 | -ret, vma->vm_start, vma->vm_pgoff); | ||
| 1192 | |||
| 1193 | return ret; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | static unsigned int ipath_poll(struct file *fp, | ||
| 1197 | struct poll_table_struct *pt) | ||
| 1198 | { | ||
| 1199 | struct ipath_portdata *pd; | ||
| 1200 | u32 head, tail; | ||
| 1201 | int bit; | ||
| 1202 | struct ipath_devdata *dd; | ||
| 1203 | |||
| 1204 | pd = port_fp(fp); | ||
| 1205 | dd = pd->port_dd; | ||
| 1206 | |||
| 1207 | bit = pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT; | ||
| 1208 | set_bit(bit, &dd->ipath_rcvctrl); | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * Before blocking, make sure that head is still == tail, | ||
| 1212 | * reading from the chip, so we can be sure the interrupt | ||
| 1213 | * enable has made it to the chip. If not equal, disable | ||
| 1214 | * interrupt again and return immediately. This avoids races, | ||
| 1215 | * and the overhead of the chip read doesn't matter much at | ||
| 1216 | * this point, since we are waiting for something anyway. | ||
| 1217 | */ | ||
| 1218 | |||
| 1219 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 1220 | dd->ipath_rcvctrl); | ||
| 1221 | |||
| 1222 | head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); | ||
| 1223 | tail = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port); | ||
| 1224 | |||
| 1225 | if (tail == head) { | ||
| 1226 | set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); | ||
| 1227 | poll_wait(fp, &pd->port_wait, pt); | ||
| 1228 | |||
| 1229 | if (test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) { | ||
| 1230 | /* timed out, no packets received */ | ||
| 1231 | clear_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); | ||
| 1232 | pd->port_rcvwait_to++; | ||
| 1233 | } | ||
| 1234 | } | ||
| 1235 | else { | ||
| 1236 | /* it's already happened; don't do wait_event overhead */ | ||
| 1237 | pd->port_rcvnowait++; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | clear_bit(bit, &dd->ipath_rcvctrl); | ||
| 1241 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 1242 | dd->ipath_rcvctrl); | ||
| 1243 | |||
| 1244 | return 0; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | static int try_alloc_port(struct ipath_devdata *dd, int port, | ||
| 1248 | struct file *fp) | ||
| 1249 | { | ||
| 1250 | int ret; | ||
| 1251 | |||
| 1252 | if (!dd->ipath_pd[port]) { | ||
| 1253 | void *p, *ptmp; | ||
| 1254 | |||
| 1255 | p = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL); | ||
| 1256 | |||
| 1257 | /* | ||
| 1258 | * Allocate memory for use in ipath_tid_update() just once | ||
| 1259 | * at open, not per call. Reduces cost of expected send | ||
| 1260 | * setup. | ||
| 1261 | */ | ||
| 1262 | ptmp = kmalloc(dd->ipath_rcvtidcnt * sizeof(u16) + | ||
| 1263 | dd->ipath_rcvtidcnt * sizeof(struct page **), | ||
| 1264 | GFP_KERNEL); | ||
| 1265 | if (!p || !ptmp) { | ||
| 1266 | ipath_dev_err(dd, "Unable to allocate portdata " | ||
| 1267 | "memory, failing open\n"); | ||
| 1268 | ret = -ENOMEM; | ||
| 1269 | kfree(p); | ||
| 1270 | kfree(ptmp); | ||
| 1271 | goto bail; | ||
| 1272 | } | ||
| 1273 | dd->ipath_pd[port] = p; | ||
| 1274 | dd->ipath_pd[port]->port_port = port; | ||
| 1275 | dd->ipath_pd[port]->port_dd = dd; | ||
| 1276 | dd->ipath_pd[port]->port_tid_pg_list = ptmp; | ||
| 1277 | init_waitqueue_head(&dd->ipath_pd[port]->port_wait); | ||
| 1278 | } | ||
| 1279 | if (!dd->ipath_pd[port]->port_cnt) { | ||
| 1280 | dd->ipath_pd[port]->port_cnt = 1; | ||
| 1281 | fp->private_data = (void *) dd->ipath_pd[port]; | ||
| 1282 | ipath_cdbg(PROC, "%s[%u] opened unit:port %u:%u\n", | ||
| 1283 | current->comm, current->pid, dd->ipath_unit, | ||
| 1284 | port); | ||
| 1285 | dd->ipath_pd[port]->port_pid = current->pid; | ||
| 1286 | strncpy(dd->ipath_pd[port]->port_comm, current->comm, | ||
| 1287 | sizeof(dd->ipath_pd[port]->port_comm)); | ||
| 1288 | ipath_stats.sps_ports++; | ||
| 1289 | ret = 0; | ||
| 1290 | goto bail; | ||
| 1291 | } | ||
| 1292 | ret = -EBUSY; | ||
| 1293 | |||
| 1294 | bail: | ||
| 1295 | return ret; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | static inline int usable(struct ipath_devdata *dd) | ||
| 1299 | { | ||
| 1300 | return dd && | ||
| 1301 | (dd->ipath_flags & IPATH_PRESENT) && | ||
| 1302 | dd->ipath_kregbase && | ||
| 1303 | dd->ipath_lid && | ||
| 1304 | !(dd->ipath_flags & (IPATH_LINKDOWN | IPATH_DISABLED | ||
| 1305 | | IPATH_LINKUNK)); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | static int find_free_port(int unit, struct file *fp) | ||
| 1309 | { | ||
| 1310 | struct ipath_devdata *dd = ipath_lookup(unit); | ||
| 1311 | int ret, i; | ||
| 1312 | |||
| 1313 | if (!dd) { | ||
| 1314 | ret = -ENODEV; | ||
| 1315 | goto bail; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | if (!usable(dd)) { | ||
| 1319 | ret = -ENETDOWN; | ||
| 1320 | goto bail; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | for (i = 0; i < dd->ipath_cfgports; i++) { | ||
| 1324 | ret = try_alloc_port(dd, i, fp); | ||
| 1325 | if (ret != -EBUSY) | ||
| 1326 | goto bail; | ||
| 1327 | } | ||
| 1328 | ret = -EBUSY; | ||
| 1329 | |||
| 1330 | bail: | ||
| 1331 | return ret; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | static int find_best_unit(struct file *fp) | ||
| 1335 | { | ||
| 1336 | int ret = 0, i, prefunit = -1, devmax; | ||
| 1337 | int maxofallports, npresent, nup; | ||
| 1338 | int ndev; | ||
| 1339 | |||
| 1340 | (void) ipath_count_units(&npresent, &nup, &maxofallports); | ||
| 1341 | |||
| 1342 | /* | ||
| 1343 | * This code is present to allow a knowledgeable person to | ||
| 1344 | * specify the layout of processes to processors before opening | ||
| 1345 | * this driver, and then we'll assign the process to the "closest" | ||
| 1346 | * HT-400 to that processor (we assume reasonable connectivity, | ||
| 1347 | * for now). This code assumes that if affinity has been set | ||
| 1348 | * before this point, that at most one cpu is set; for now this | ||
| 1349 | * is reasonable. I check for both cpus_empty() and cpus_full(), | ||
| 1350 | * in case some kernel variant sets none of the bits when no | ||
| 1351 | * affinity is set. 2.6.11 and 12 kernels have all present | ||
| 1352 | * cpus set. Some day we'll have to fix it up further to handle | ||
| 1353 | * a cpu subset. This algorithm fails for two HT-400's connected | ||
| 1354 | * in tunnel fashion. Eventually this needs real topology | ||
| 1355 | * information. There may be some issues with dual core numbering | ||
| 1356 | * as well. This needs more work prior to release. | ||
| 1357 | */ | ||
| 1358 | if (!cpus_empty(current->cpus_allowed) && | ||
| 1359 | !cpus_full(current->cpus_allowed)) { | ||
| 1360 | int ncpus = num_online_cpus(), curcpu = -1; | ||
| 1361 | for (i = 0; i < ncpus; i++) | ||
| 1362 | if (cpu_isset(i, current->cpus_allowed)) { | ||
| 1363 | ipath_cdbg(PROC, "%s[%u] affinity set for " | ||
| 1364 | "cpu %d\n", current->comm, | ||
| 1365 | current->pid, i); | ||
| 1366 | curcpu = i; | ||
| 1367 | } | ||
| 1368 | if (curcpu != -1) { | ||
| 1369 | if (npresent) { | ||
| 1370 | prefunit = curcpu / (ncpus / npresent); | ||
| 1371 | ipath_dbg("%s[%u] %d chips, %d cpus, " | ||
| 1372 | "%d cpus/chip, select unit %d\n", | ||
| 1373 | current->comm, current->pid, | ||
| 1374 | npresent, ncpus, ncpus / npresent, | ||
| 1375 | prefunit); | ||
| 1376 | } | ||
| 1377 | } | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | /* | ||
| 1381 | * user ports start at 1, kernel port is 0 | ||
| 1382 | * For now, we do round-robin access across all chips | ||
| 1383 | */ | ||
| 1384 | |||
| 1385 | if (prefunit != -1) | ||
| 1386 | devmax = prefunit + 1; | ||
| 1387 | else | ||
| 1388 | devmax = ipath_count_units(NULL, NULL, NULL); | ||
| 1389 | recheck: | ||
| 1390 | for (i = 1; i < maxofallports; i++) { | ||
| 1391 | for (ndev = prefunit != -1 ? prefunit : 0; ndev < devmax; | ||
| 1392 | ndev++) { | ||
| 1393 | struct ipath_devdata *dd = ipath_lookup(ndev); | ||
| 1394 | |||
| 1395 | if (!usable(dd)) | ||
| 1396 | continue; /* can't use this unit */ | ||
| 1397 | if (i >= dd->ipath_cfgports) | ||
| 1398 | /* | ||
| 1399 | * Maxed out on users of this unit. Try | ||
| 1400 | * next. | ||
| 1401 | */ | ||
| 1402 | continue; | ||
| 1403 | ret = try_alloc_port(dd, i, fp); | ||
| 1404 | if (!ret) | ||
| 1405 | goto done; | ||
| 1406 | } | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | if (npresent) { | ||
| 1410 | if (nup == 0) { | ||
| 1411 | ret = -ENETDOWN; | ||
| 1412 | ipath_dbg("No ports available (none initialized " | ||
| 1413 | "and ready)\n"); | ||
| 1414 | } else { | ||
| 1415 | if (prefunit > 0) { | ||
| 1416 | /* if started above 0, retry from 0 */ | ||
| 1417 | ipath_cdbg(PROC, | ||
| 1418 | "%s[%u] no ports on prefunit " | ||
| 1419 | "%d, clear and re-check\n", | ||
| 1420 | current->comm, current->pid, | ||
| 1421 | prefunit); | ||
| 1422 | devmax = ipath_count_units(NULL, NULL, | ||
| 1423 | NULL); | ||
| 1424 | prefunit = -1; | ||
| 1425 | goto recheck; | ||
| 1426 | } | ||
| 1427 | ret = -EBUSY; | ||
| 1428 | ipath_dbg("No ports available\n"); | ||
| 1429 | } | ||
| 1430 | } else { | ||
| 1431 | ret = -ENXIO; | ||
| 1432 | ipath_dbg("No boards found\n"); | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | done: | ||
| 1436 | return ret; | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | static int ipath_open(struct inode *in, struct file *fp) | ||
| 1440 | { | ||
| 1441 | int ret, minor; | ||
| 1442 | |||
| 1443 | mutex_lock(&ipath_mutex); | ||
| 1444 | |||
| 1445 | minor = iminor(in); | ||
| 1446 | ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n", | ||
| 1447 | (long)in->i_rdev, minor); | ||
| 1448 | |||
| 1449 | if (minor) | ||
| 1450 | ret = find_free_port(minor - 1, fp); | ||
| 1451 | else | ||
| 1452 | ret = find_best_unit(fp); | ||
| 1453 | |||
| 1454 | mutex_unlock(&ipath_mutex); | ||
| 1455 | return ret; | ||
| 1456 | } | ||
| 1457 | |||
| 1458 | /** | ||
| 1459 | * unlock_exptid - unlock any expected TID entries port still had in use | ||
| 1460 | * @pd: port | ||
| 1461 | * | ||
| 1462 | * We don't actually update the chip here, because we do a bulk update | ||
| 1463 | * below, using ipath_f_clear_tids. | ||
| 1464 | */ | ||
| 1465 | static void unlock_expected_tids(struct ipath_portdata *pd) | ||
| 1466 | { | ||
| 1467 | struct ipath_devdata *dd = pd->port_dd; | ||
| 1468 | int port_tidbase = pd->port_port * dd->ipath_rcvtidcnt; | ||
| 1469 | int i, cnt = 0, maxtid = port_tidbase + dd->ipath_rcvtidcnt; | ||
| 1470 | |||
| 1471 | ipath_cdbg(VERBOSE, "Port %u unlocking any locked expTID pages\n", | ||
| 1472 | pd->port_port); | ||
| 1473 | for (i = port_tidbase; i < maxtid; i++) { | ||
| 1474 | if (!dd->ipath_pageshadow[i]) | ||
| 1475 | continue; | ||
| 1476 | |||
| 1477 | ipath_release_user_pages_on_close(&dd->ipath_pageshadow[i], | ||
| 1478 | 1); | ||
| 1479 | dd->ipath_pageshadow[i] = NULL; | ||
| 1480 | cnt++; | ||
| 1481 | ipath_stats.sps_pageunlocks++; | ||
| 1482 | } | ||
| 1483 | if (cnt) | ||
| 1484 | ipath_cdbg(VERBOSE, "Port %u locked %u expTID entries\n", | ||
| 1485 | pd->port_port, cnt); | ||
| 1486 | |||
| 1487 | if (ipath_stats.sps_pagelocks || ipath_stats.sps_pageunlocks) | ||
| 1488 | ipath_cdbg(VERBOSE, "%llu pages locked, %llu unlocked\n", | ||
| 1489 | (unsigned long long) ipath_stats.sps_pagelocks, | ||
| 1490 | (unsigned long long) | ||
| 1491 | ipath_stats.sps_pageunlocks); | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | static int ipath_close(struct inode *in, struct file *fp) | ||
| 1495 | { | ||
| 1496 | int ret = 0; | ||
| 1497 | struct ipath_portdata *pd; | ||
| 1498 | struct ipath_devdata *dd; | ||
| 1499 | unsigned port; | ||
| 1500 | |||
| 1501 | ipath_cdbg(VERBOSE, "close on dev %lx, private data %p\n", | ||
| 1502 | (long)in->i_rdev, fp->private_data); | ||
| 1503 | |||
| 1504 | mutex_lock(&ipath_mutex); | ||
| 1505 | |||
| 1506 | pd = port_fp(fp); | ||
| 1507 | port = pd->port_port; | ||
| 1508 | fp->private_data = NULL; | ||
| 1509 | dd = pd->port_dd; | ||
| 1510 | |||
| 1511 | if (pd->port_hdrqfull) { | ||
| 1512 | ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors " | ||
| 1513 | "during run\n", pd->port_comm, pd->port_pid, | ||
| 1514 | pd->port_hdrqfull); | ||
| 1515 | pd->port_hdrqfull = 0; | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | if (pd->port_rcvwait_to || pd->port_piowait_to | ||
| 1519 | || pd->port_rcvnowait || pd->port_pionowait) { | ||
| 1520 | ipath_cdbg(VERBOSE, "port%u, %u rcv, %u pio wait timeo; " | ||
| 1521 | "%u rcv %u, pio already\n", | ||
| 1522 | pd->port_port, pd->port_rcvwait_to, | ||
| 1523 | pd->port_piowait_to, pd->port_rcvnowait, | ||
| 1524 | pd->port_pionowait); | ||
| 1525 | pd->port_rcvwait_to = pd->port_piowait_to = | ||
| 1526 | pd->port_rcvnowait = pd->port_pionowait = 0; | ||
| 1527 | } | ||
| 1528 | if (pd->port_flag) { | ||
| 1529 | ipath_dbg("port %u port_flag still set to 0x%lx\n", | ||
| 1530 | pd->port_port, pd->port_flag); | ||
| 1531 | pd->port_flag = 0; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | if (dd->ipath_kregbase) { | ||
| 1535 | if (pd->port_rcvhdrtail_uaddr) { | ||
| 1536 | pd->port_rcvhdrtail_uaddr = 0; | ||
| 1537 | pd->port_rcvhdrtail_kvaddr = NULL; | ||
| 1538 | ipath_release_user_pages_on_close( | ||
| 1539 | &pd->port_rcvhdrtail_pagep, 1); | ||
| 1540 | pd->port_rcvhdrtail_pagep = NULL; | ||
| 1541 | ipath_stats.sps_pageunlocks++; | ||
| 1542 | } | ||
| 1543 | ipath_write_kreg_port( | ||
| 1544 | dd, dd->ipath_kregs->kr_rcvhdrtailaddr, | ||
| 1545 | port, 0ULL); | ||
| 1546 | ipath_write_kreg_port( | ||
| 1547 | dd, dd->ipath_kregs->kr_rcvhdraddr, | ||
| 1548 | pd->port_port, 0); | ||
| 1549 | |||
| 1550 | /* clean up the pkeys for this port user */ | ||
| 1551 | ipath_clean_part_key(pd, dd); | ||
| 1552 | |||
| 1553 | if (port < dd->ipath_cfgports) { | ||
| 1554 | int i = dd->ipath_pbufsport * (port - 1); | ||
| 1555 | ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport); | ||
| 1556 | |||
| 1557 | /* atomically clear receive enable port. */ | ||
| 1558 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + port, | ||
| 1559 | &dd->ipath_rcvctrl); | ||
| 1560 | ipath_write_kreg( | ||
| 1561 | dd, | ||
| 1562 | dd->ipath_kregs->kr_rcvctrl, | ||
| 1563 | dd->ipath_rcvctrl); | ||
| 1564 | |||
| 1565 | if (dd->ipath_pageshadow) | ||
| 1566 | unlock_expected_tids(pd); | ||
| 1567 | ipath_stats.sps_ports--; | ||
| 1568 | ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", | ||
| 1569 | pd->port_comm, pd->port_pid, | ||
| 1570 | dd->ipath_unit, port); | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | pd->port_cnt = 0; | ||
| 1575 | pd->port_pid = 0; | ||
| 1576 | |||
| 1577 | dd->ipath_f_clear_tids(dd, pd->port_port); | ||
| 1578 | |||
| 1579 | ipath_free_pddata(dd, pd->port_port, 0); | ||
| 1580 | |||
| 1581 | mutex_unlock(&ipath_mutex); | ||
| 1582 | |||
| 1583 | return ret; | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | static int ipath_port_info(struct ipath_portdata *pd, | ||
| 1587 | struct ipath_port_info __user *uinfo) | ||
| 1588 | { | ||
| 1589 | struct ipath_port_info info; | ||
| 1590 | int nup; | ||
| 1591 | int ret; | ||
| 1592 | |||
| 1593 | (void) ipath_count_units(NULL, &nup, NULL); | ||
| 1594 | info.num_active = nup; | ||
| 1595 | info.unit = pd->port_dd->ipath_unit; | ||
| 1596 | info.port = pd->port_port; | ||
| 1597 | |||
| 1598 | if (copy_to_user(uinfo, &info, sizeof(info))) { | ||
| 1599 | ret = -EFAULT; | ||
| 1600 | goto bail; | ||
| 1601 | } | ||
| 1602 | ret = 0; | ||
| 1603 | |||
| 1604 | bail: | ||
| 1605 | return ret; | ||
| 1606 | } | ||
| 1607 | |||
| 1608 | static ssize_t ipath_write(struct file *fp, const char __user *data, | ||
| 1609 | size_t count, loff_t *off) | ||
| 1610 | { | ||
| 1611 | const struct ipath_cmd __user *ucmd; | ||
| 1612 | struct ipath_portdata *pd; | ||
| 1613 | const void __user *src; | ||
| 1614 | size_t consumed, copy; | ||
| 1615 | struct ipath_cmd cmd; | ||
| 1616 | ssize_t ret = 0; | ||
| 1617 | void *dest; | ||
| 1618 | |||
| 1619 | if (count < sizeof(cmd.type)) { | ||
| 1620 | ret = -EINVAL; | ||
| 1621 | goto bail; | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | ucmd = (const struct ipath_cmd __user *) data; | ||
| 1625 | |||
| 1626 | if (copy_from_user(&cmd.type, &ucmd->type, sizeof(cmd.type))) { | ||
| 1627 | ret = -EFAULT; | ||
| 1628 | goto bail; | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | consumed = sizeof(cmd.type); | ||
| 1632 | |||
| 1633 | switch (cmd.type) { | ||
| 1634 | case IPATH_CMD_USER_INIT: | ||
| 1635 | copy = sizeof(cmd.cmd.user_info); | ||
| 1636 | dest = &cmd.cmd.user_info; | ||
| 1637 | src = &ucmd->cmd.user_info; | ||
| 1638 | break; | ||
| 1639 | case IPATH_CMD_RECV_CTRL: | ||
| 1640 | copy = sizeof(cmd.cmd.recv_ctrl); | ||
| 1641 | dest = &cmd.cmd.recv_ctrl; | ||
| 1642 | src = &ucmd->cmd.recv_ctrl; | ||
| 1643 | break; | ||
| 1644 | case IPATH_CMD_PORT_INFO: | ||
| 1645 | copy = sizeof(cmd.cmd.port_info); | ||
| 1646 | dest = &cmd.cmd.port_info; | ||
| 1647 | src = &ucmd->cmd.port_info; | ||
| 1648 | break; | ||
| 1649 | case IPATH_CMD_TID_UPDATE: | ||
| 1650 | case IPATH_CMD_TID_FREE: | ||
| 1651 | copy = sizeof(cmd.cmd.tid_info); | ||
| 1652 | dest = &cmd.cmd.tid_info; | ||
| 1653 | src = &ucmd->cmd.tid_info; | ||
| 1654 | break; | ||
| 1655 | case IPATH_CMD_SET_PART_KEY: | ||
| 1656 | copy = sizeof(cmd.cmd.part_key); | ||
| 1657 | dest = &cmd.cmd.part_key; | ||
| 1658 | src = &ucmd->cmd.part_key; | ||
| 1659 | break; | ||
| 1660 | default: | ||
| 1661 | ret = -EINVAL; | ||
| 1662 | goto bail; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | if ((count - consumed) < copy) { | ||
| 1666 | ret = -EINVAL; | ||
| 1667 | goto bail; | ||
| 1668 | } | ||
| 1669 | |||
| 1670 | if (copy_from_user(dest, src, copy)) { | ||
| 1671 | ret = -EFAULT; | ||
| 1672 | goto bail; | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | consumed += copy; | ||
| 1676 | pd = port_fp(fp); | ||
| 1677 | |||
| 1678 | switch (cmd.type) { | ||
| 1679 | case IPATH_CMD_USER_INIT: | ||
| 1680 | ret = ipath_do_user_init(pd, &cmd.cmd.user_info); | ||
| 1681 | if (ret < 0) | ||
| 1682 | goto bail; | ||
| 1683 | ret = ipath_get_base_info( | ||
| 1684 | pd, (void __user *) (unsigned long) | ||
| 1685 | cmd.cmd.user_info.spu_base_info, | ||
| 1686 | cmd.cmd.user_info.spu_base_info_size); | ||
| 1687 | break; | ||
| 1688 | case IPATH_CMD_RECV_CTRL: | ||
| 1689 | ret = ipath_manage_rcvq(pd, cmd.cmd.recv_ctrl); | ||
| 1690 | break; | ||
| 1691 | case IPATH_CMD_PORT_INFO: | ||
| 1692 | ret = ipath_port_info(pd, | ||
| 1693 | (struct ipath_port_info __user *) | ||
| 1694 | (unsigned long) cmd.cmd.port_info); | ||
| 1695 | break; | ||
| 1696 | case IPATH_CMD_TID_UPDATE: | ||
| 1697 | ret = ipath_tid_update(pd, &cmd.cmd.tid_info); | ||
| 1698 | break; | ||
| 1699 | case IPATH_CMD_TID_FREE: | ||
| 1700 | ret = ipath_tid_free(pd, &cmd.cmd.tid_info); | ||
| 1701 | break; | ||
| 1702 | case IPATH_CMD_SET_PART_KEY: | ||
| 1703 | ret = ipath_set_part_key(pd, cmd.cmd.part_key); | ||
| 1704 | break; | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | if (ret >= 0) | ||
| 1708 | ret = consumed; | ||
| 1709 | |||
| 1710 | bail: | ||
| 1711 | return ret; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | static struct class *ipath_class; | ||
| 1715 | |||
| 1716 | static int init_cdev(int minor, char *name, struct file_operations *fops, | ||
| 1717 | struct cdev **cdevp, struct class_device **class_devp) | ||
| 1718 | { | ||
| 1719 | const dev_t dev = MKDEV(IPATH_MAJOR, minor); | ||
| 1720 | struct cdev *cdev = NULL; | ||
| 1721 | struct class_device *class_dev = NULL; | ||
| 1722 | int ret; | ||
| 1723 | |||
| 1724 | cdev = cdev_alloc(); | ||
| 1725 | if (!cdev) { | ||
| 1726 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 1727 | ": Could not allocate cdev for minor %d, %s\n", | ||
| 1728 | minor, name); | ||
| 1729 | ret = -ENOMEM; | ||
| 1730 | goto done; | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | cdev->owner = THIS_MODULE; | ||
| 1734 | cdev->ops = fops; | ||
| 1735 | kobject_set_name(&cdev->kobj, name); | ||
| 1736 | |||
| 1737 | ret = cdev_add(cdev, dev, 1); | ||
| 1738 | if (ret < 0) { | ||
| 1739 | printk(KERN_ERR IPATH_DRV_NAME | ||
| 1740 | ": Could not add cdev for minor %d, %s (err %d)\n", | ||
| 1741 | minor, name, -ret); | ||
| 1742 | goto err_cdev; | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | class_dev = class_device_create(ipath_class, NULL, dev, NULL, name); | ||
| 1746 | |||
| 1747 | if (IS_ERR(class_dev)) { | ||
| 1748 | ret = PTR_ERR(class_dev); | ||
| 1749 | printk(KERN_ERR IPATH_DRV_NAME ": Could not create " | ||
| 1750 | "class_dev for minor %d, %s (err %d)\n", | ||
| 1751 | minor, name, -ret); | ||
| 1752 | goto err_cdev; | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | goto done; | ||
| 1756 | |||
| 1757 | err_cdev: | ||
| 1758 | cdev_del(cdev); | ||
| 1759 | cdev = NULL; | ||
| 1760 | |||
| 1761 | done: | ||
| 1762 | if (ret >= 0) { | ||
| 1763 | *cdevp = cdev; | ||
| 1764 | *class_devp = class_dev; | ||
| 1765 | } else { | ||
| 1766 | *cdevp = NULL; | ||
| 1767 | *class_devp = NULL; | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | return ret; | ||
| 1771 | } | ||
| 1772 | |||
| 1773 | int ipath_cdev_init(int minor, char *name, struct file_operations *fops, | ||
| 1774 | struct cdev **cdevp, struct class_device **class_devp) | ||
| 1775 | { | ||
| 1776 | return init_cdev(minor, name, fops, cdevp, class_devp); | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | static void cleanup_cdev(struct cdev **cdevp, | ||
| 1780 | struct class_device **class_devp) | ||
| 1781 | { | ||
| 1782 | struct class_device *class_dev = *class_devp; | ||
| 1783 | |||
| 1784 | if (class_dev) { | ||
| 1785 | class_device_unregister(class_dev); | ||
| 1786 | *class_devp = NULL; | ||
| 1787 | } | ||
| 1788 | |||
| 1789 | if (*cdevp) { | ||
| 1790 | cdev_del(*cdevp); | ||
| 1791 | *cdevp = NULL; | ||
| 1792 | } | ||
| 1793 | } | ||
| 1794 | |||
| 1795 | void ipath_cdev_cleanup(struct cdev **cdevp, | ||
| 1796 | struct class_device **class_devp) | ||
| 1797 | { | ||
| 1798 | cleanup_cdev(cdevp, class_devp); | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | static struct cdev *wildcard_cdev; | ||
| 1802 | static struct class_device *wildcard_class_dev; | ||
| 1803 | |||
| 1804 | static const dev_t dev = MKDEV(IPATH_MAJOR, 0); | ||
| 1805 | |||
| 1806 | static int user_init(void) | ||
| 1807 | { | ||
| 1808 | int ret; | ||
| 1809 | |||
| 1810 | ret = register_chrdev_region(dev, IPATH_NMINORS, IPATH_DRV_NAME); | ||
| 1811 | if (ret < 0) { | ||
| 1812 | printk(KERN_ERR IPATH_DRV_NAME ": Could not register " | ||
| 1813 | "chrdev region (err %d)\n", -ret); | ||
| 1814 | goto done; | ||
| 1815 | } | ||
| 1816 | |||
| 1817 | ipath_class = class_create(THIS_MODULE, IPATH_DRV_NAME); | ||
| 1818 | |||
| 1819 | if (IS_ERR(ipath_class)) { | ||
| 1820 | ret = PTR_ERR(ipath_class); | ||
| 1821 | printk(KERN_ERR IPATH_DRV_NAME ": Could not create " | ||
| 1822 | "device class (err %d)\n", -ret); | ||
| 1823 | goto bail; | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | goto done; | ||
| 1827 | bail: | ||
| 1828 | unregister_chrdev_region(dev, IPATH_NMINORS); | ||
| 1829 | done: | ||
| 1830 | return ret; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | static void user_cleanup(void) | ||
| 1834 | { | ||
| 1835 | if (ipath_class) { | ||
| 1836 | class_destroy(ipath_class); | ||
| 1837 | ipath_class = NULL; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | unregister_chrdev_region(dev, IPATH_NMINORS); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | static atomic_t user_count = ATOMIC_INIT(0); | ||
| 1844 | static atomic_t user_setup = ATOMIC_INIT(0); | ||
| 1845 | |||
| 1846 | int ipath_user_add(struct ipath_devdata *dd) | ||
| 1847 | { | ||
| 1848 | char name[10]; | ||
| 1849 | int ret; | ||
| 1850 | |||
| 1851 | if (atomic_inc_return(&user_count) == 1) { | ||
| 1852 | ret = user_init(); | ||
| 1853 | if (ret < 0) { | ||
| 1854 | ipath_dev_err(dd, "Unable to set up user support: " | ||
| 1855 | "error %d\n", -ret); | ||
| 1856 | goto bail; | ||
| 1857 | } | ||
| 1858 | ret = ipath_diag_init(); | ||
| 1859 | if (ret < 0) { | ||
| 1860 | ipath_dev_err(dd, "Unable to set up diag support: " | ||
| 1861 | "error %d\n", -ret); | ||
| 1862 | goto bail_sma; | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | ret = init_cdev(0, "ipath", &ipath_file_ops, &wildcard_cdev, | ||
| 1866 | &wildcard_class_dev); | ||
| 1867 | if (ret < 0) { | ||
| 1868 | ipath_dev_err(dd, "Could not create wildcard " | ||
| 1869 | "minor: error %d\n", -ret); | ||
| 1870 | goto bail_diag; | ||
| 1871 | } | ||
| 1872 | |||
| 1873 | atomic_set(&user_setup, 1); | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | snprintf(name, sizeof(name), "ipath%d", dd->ipath_unit); | ||
| 1877 | |||
| 1878 | ret = init_cdev(dd->ipath_unit + 1, name, &ipath_file_ops, | ||
| 1879 | &dd->cdev, &dd->class_dev); | ||
| 1880 | if (ret < 0) | ||
| 1881 | ipath_dev_err(dd, "Could not create user minor %d, %s\n", | ||
| 1882 | dd->ipath_unit + 1, name); | ||
| 1883 | |||
| 1884 | goto bail; | ||
| 1885 | |||
| 1886 | bail_diag: | ||
| 1887 | ipath_diag_cleanup(); | ||
| 1888 | bail_sma: | ||
| 1889 | user_cleanup(); | ||
| 1890 | bail: | ||
| 1891 | return ret; | ||
| 1892 | } | ||
| 1893 | |||
| 1894 | void ipath_user_del(struct ipath_devdata *dd) | ||
| 1895 | { | ||
| 1896 | cleanup_cdev(&dd->cdev, &dd->class_dev); | ||
| 1897 | |||
| 1898 | if (atomic_dec_return(&user_count) == 0) { | ||
| 1899 | if (atomic_read(&user_setup) == 0) | ||
| 1900 | goto bail; | ||
| 1901 | |||
| 1902 | cleanup_cdev(&wildcard_cdev, &wildcard_class_dev); | ||
| 1903 | ipath_diag_cleanup(); | ||
| 1904 | user_cleanup(); | ||
| 1905 | |||
| 1906 | atomic_set(&user_setup, 0); | ||
| 1907 | } | ||
| 1908 | bail: | ||
| 1909 | return; | ||
| 1910 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c new file mode 100644 index 000000000000..e274120567e1 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
| @@ -0,0 +1,605 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/version.h> | ||
| 34 | #include <linux/config.h> | ||
| 35 | #include <linux/module.h> | ||
| 36 | #include <linux/fs.h> | ||
| 37 | #include <linux/mount.h> | ||
| 38 | #include <linux/pagemap.h> | ||
| 39 | #include <linux/init.h> | ||
| 40 | #include <linux/namei.h> | ||
| 41 | #include <linux/pci.h> | ||
| 42 | |||
| 43 | #include "ipath_kernel.h" | ||
| 44 | |||
| 45 | #define IPATHFS_MAGIC 0x726a77 | ||
| 46 | |||
| 47 | static struct super_block *ipath_super; | ||
| 48 | |||
| 49 | static int ipathfs_mknod(struct inode *dir, struct dentry *dentry, | ||
| 50 | int mode, struct file_operations *fops, | ||
| 51 | void *data) | ||
| 52 | { | ||
| 53 | int error; | ||
| 54 | struct inode *inode = new_inode(dir->i_sb); | ||
| 55 | |||
| 56 | if (!inode) { | ||
| 57 | error = -EPERM; | ||
| 58 | goto bail; | ||
| 59 | } | ||
| 60 | |||
| 61 | inode->i_mode = mode; | ||
| 62 | inode->i_uid = 0; | ||
| 63 | inode->i_gid = 0; | ||
| 64 | inode->i_blksize = PAGE_CACHE_SIZE; | ||
| 65 | inode->i_blocks = 0; | ||
| 66 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 67 | inode->u.generic_ip = data; | ||
| 68 | if ((mode & S_IFMT) == S_IFDIR) { | ||
| 69 | inode->i_op = &simple_dir_inode_operations; | ||
| 70 | inode->i_nlink++; | ||
| 71 | dir->i_nlink++; | ||
| 72 | } | ||
| 73 | |||
| 74 | inode->i_fop = fops; | ||
| 75 | |||
| 76 | d_instantiate(dentry, inode); | ||
| 77 | error = 0; | ||
| 78 | |||
| 79 | bail: | ||
| 80 | return error; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int create_file(const char *name, mode_t mode, | ||
| 84 | struct dentry *parent, struct dentry **dentry, | ||
| 85 | struct file_operations *fops, void *data) | ||
| 86 | { | ||
| 87 | int error; | ||
| 88 | |||
| 89 | *dentry = NULL; | ||
| 90 | mutex_lock(&parent->d_inode->i_mutex); | ||
| 91 | *dentry = lookup_one_len(name, parent, strlen(name)); | ||
| 92 | if (!IS_ERR(dentry)) | ||
| 93 | error = ipathfs_mknod(parent->d_inode, *dentry, | ||
| 94 | mode, fops, data); | ||
| 95 | else | ||
| 96 | error = PTR_ERR(dentry); | ||
| 97 | mutex_unlock(&parent->d_inode->i_mutex); | ||
| 98 | |||
| 99 | return error; | ||
| 100 | } | ||
| 101 | |||
| 102 | static ssize_t atomic_stats_read(struct file *file, char __user *buf, | ||
| 103 | size_t count, loff_t *ppos) | ||
| 104 | { | ||
| 105 | return simple_read_from_buffer(buf, count, ppos, &ipath_stats, | ||
| 106 | sizeof ipath_stats); | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct file_operations atomic_stats_ops = { | ||
| 110 | .read = atomic_stats_read, | ||
| 111 | }; | ||
| 112 | |||
| 113 | #define NUM_COUNTERS sizeof(struct infinipath_counters) / sizeof(u64) | ||
| 114 | |||
| 115 | static ssize_t atomic_counters_read(struct file *file, char __user *buf, | ||
| 116 | size_t count, loff_t *ppos) | ||
| 117 | { | ||
| 118 | u64 counters[NUM_COUNTERS]; | ||
| 119 | u16 i; | ||
| 120 | struct ipath_devdata *dd; | ||
| 121 | |||
| 122 | dd = file->f_dentry->d_inode->u.generic_ip; | ||
| 123 | |||
| 124 | for (i = 0; i < NUM_COUNTERS; i++) | ||
| 125 | counters[i] = ipath_snap_cntr(dd, i); | ||
| 126 | |||
| 127 | return simple_read_from_buffer(buf, count, ppos, counters, | ||
| 128 | sizeof counters); | ||
| 129 | } | ||
| 130 | |||
| 131 | static struct file_operations atomic_counters_ops = { | ||
| 132 | .read = atomic_counters_read, | ||
| 133 | }; | ||
| 134 | |||
| 135 | static ssize_t atomic_node_info_read(struct file *file, char __user *buf, | ||
| 136 | size_t count, loff_t *ppos) | ||
| 137 | { | ||
| 138 | u32 nodeinfo[10]; | ||
| 139 | struct ipath_devdata *dd; | ||
| 140 | u64 guid; | ||
| 141 | |||
| 142 | dd = file->f_dentry->d_inode->u.generic_ip; | ||
| 143 | |||
| 144 | guid = be64_to_cpu(dd->ipath_guid); | ||
| 145 | |||
| 146 | nodeinfo[0] = /* BaseVersion is SMA */ | ||
| 147 | /* ClassVersion is SMA */ | ||
| 148 | (1 << 8) /* NodeType */ | ||
| 149 | | (1 << 0); /* NumPorts */ | ||
| 150 | nodeinfo[1] = (u32) (guid >> 32); | ||
| 151 | nodeinfo[2] = (u32) (guid & 0xffffffff); | ||
| 152 | /* PortGUID == SystemImageGUID for us */ | ||
| 153 | nodeinfo[3] = nodeinfo[1]; | ||
| 154 | /* PortGUID == SystemImageGUID for us */ | ||
| 155 | nodeinfo[4] = nodeinfo[2]; | ||
| 156 | /* PortGUID == NodeGUID for us */ | ||
| 157 | nodeinfo[5] = nodeinfo[3]; | ||
| 158 | /* PortGUID == NodeGUID for us */ | ||
| 159 | nodeinfo[6] = nodeinfo[4]; | ||
| 160 | nodeinfo[7] = (4 << 16) /* we support 4 pkeys */ | ||
| 161 | | (dd->ipath_deviceid << 0); | ||
| 162 | /* our chip version as 16 bits major, 16 bits minor */ | ||
| 163 | nodeinfo[8] = dd->ipath_minrev | (dd->ipath_majrev << 16); | ||
| 164 | nodeinfo[9] = (dd->ipath_unit << 24) | (dd->ipath_vendorid << 0); | ||
| 165 | |||
| 166 | return simple_read_from_buffer(buf, count, ppos, nodeinfo, | ||
| 167 | sizeof nodeinfo); | ||
| 168 | } | ||
| 169 | |||
| 170 | static struct file_operations atomic_node_info_ops = { | ||
| 171 | .read = atomic_node_info_read, | ||
| 172 | }; | ||
| 173 | |||
| 174 | static ssize_t atomic_port_info_read(struct file *file, char __user *buf, | ||
| 175 | size_t count, loff_t *ppos) | ||
| 176 | { | ||
| 177 | u32 portinfo[13]; | ||
| 178 | u32 tmp, tmp2; | ||
| 179 | struct ipath_devdata *dd; | ||
| 180 | |||
| 181 | dd = file->f_dentry->d_inode->u.generic_ip; | ||
| 182 | |||
| 183 | /* so we only initialize non-zero fields. */ | ||
| 184 | memset(portinfo, 0, sizeof portinfo); | ||
| 185 | |||
| 186 | /* | ||
| 187 | * Notimpl yet M_Key (64) | ||
| 188 | * Notimpl yet GID (64) | ||
| 189 | */ | ||
| 190 | |||
| 191 | portinfo[4] = (dd->ipath_lid << 16); | ||
| 192 | |||
| 193 | /* | ||
| 194 | * Notimpl yet SMLID (should we store this in the driver, in case | ||
| 195 | * SMA dies?) CapabilityMask is 0, we don't support any of these | ||
| 196 | * DiagCode is 0; we don't store any diag info for now Notimpl yet | ||
| 197 | * M_KeyLeasePeriod (we don't support M_Key) | ||
| 198 | */ | ||
| 199 | |||
| 200 | /* LocalPortNum is whichever port number they ask for */ | ||
| 201 | portinfo[7] = (dd->ipath_unit << 24) | ||
| 202 | /* LinkWidthEnabled */ | ||
| 203 | | (2 << 16) | ||
| 204 | /* LinkWidthSupported (really 2, but not IB valid) */ | ||
| 205 | | (3 << 8) | ||
| 206 | /* LinkWidthActive */ | ||
| 207 | | (2 << 0); | ||
| 208 | tmp = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK; | ||
| 209 | tmp2 = 5; | ||
| 210 | if (tmp == IPATH_IBSTATE_INIT) | ||
| 211 | tmp = 2; | ||
| 212 | else if (tmp == IPATH_IBSTATE_ARM) | ||
| 213 | tmp = 3; | ||
| 214 | else if (tmp == IPATH_IBSTATE_ACTIVE) | ||
| 215 | tmp = 4; | ||
| 216 | else { | ||
| 217 | tmp = 0; /* down */ | ||
| 218 | tmp2 = tmp & 0xf; | ||
| 219 | } | ||
| 220 | |||
| 221 | portinfo[8] = (1 << 28) /* LinkSpeedSupported */ | ||
| 222 | | (tmp << 24) /* PortState */ | ||
| 223 | | (tmp2 << 20) /* PortPhysicalState */ | ||
| 224 | | (2 << 16) | ||
| 225 | |||
| 226 | /* LinkDownDefaultState */ | ||
| 227 | /* M_KeyProtectBits == 0 */ | ||
| 228 | /* NotImpl yet LMC == 0 (we can support all values) */ | ||
| 229 | | (1 << 4) /* LinkSpeedActive */ | ||
| 230 | | (1 << 0); /* LinkSpeedEnabled */ | ||
| 231 | switch (dd->ipath_ibmtu) { | ||
| 232 | case 4096: | ||
| 233 | tmp = 5; | ||
| 234 | break; | ||
| 235 | case 2048: | ||
| 236 | tmp = 4; | ||
| 237 | break; | ||
| 238 | case 1024: | ||
| 239 | tmp = 3; | ||
| 240 | break; | ||
| 241 | case 512: | ||
| 242 | tmp = 2; | ||
| 243 | break; | ||
| 244 | case 256: | ||
| 245 | tmp = 1; | ||
| 246 | break; | ||
| 247 | default: /* oops, something is wrong */ | ||
| 248 | ipath_dbg("Problem, ipath_ibmtu 0x%x not a valid IB MTU, " | ||
| 249 | "treat as 2048\n", dd->ipath_ibmtu); | ||
| 250 | tmp = 4; | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | portinfo[9] = (tmp << 28) | ||
| 254 | /* NeighborMTU */ | ||
| 255 | /* Notimpl MasterSMSL */ | ||
| 256 | | (1 << 20) | ||
| 257 | |||
| 258 | /* VLCap */ | ||
| 259 | /* Notimpl InitType (actually, an SMA decision) */ | ||
| 260 | /* VLHighLimit is 0 (only one VL) */ | ||
| 261 | ; /* VLArbitrationHighCap is 0 (only one VL) */ | ||
| 262 | portinfo[10] = /* VLArbitrationLowCap is 0 (only one VL) */ | ||
| 263 | /* InitTypeReply is SMA decision */ | ||
| 264 | (5 << 16) /* MTUCap 4096 */ | ||
| 265 | | (7 << 13) /* VLStallCount */ | ||
| 266 | | (0x1f << 8) /* HOQLife */ | ||
| 267 | | (1 << 4) | ||
| 268 | |||
| 269 | /* OperationalVLs 0 */ | ||
| 270 | /* PartitionEnforcementInbound */ | ||
| 271 | /* PartitionEnforcementOutbound not enforced */ | ||
| 272 | /* FilterRawinbound not enforced */ | ||
| 273 | ; /* FilterRawOutbound not enforced */ | ||
| 274 | /* M_KeyViolations are not counted by hardware, SMA can count */ | ||
| 275 | tmp = ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey); | ||
| 276 | /* P_KeyViolations are counted by hardware. */ | ||
| 277 | portinfo[11] = ((tmp & 0xffff) << 0); | ||
| 278 | portinfo[12] = | ||
| 279 | /* Q_KeyViolations are not counted by hardware */ | ||
| 280 | (1 << 8) | ||
| 281 | |||
| 282 | /* GUIDCap */ | ||
| 283 | /* SubnetTimeOut handled by SMA */ | ||
| 284 | /* RespTimeValue handled by SMA */ | ||
| 285 | ; | ||
| 286 | /* LocalPhyErrors are programmed to max */ | ||
| 287 | portinfo[12] |= (0xf << 20) | ||
| 288 | | (0xf << 16) /* OverRunErrors are programmed to max */ | ||
| 289 | ; | ||
| 290 | |||
| 291 | return simple_read_from_buffer(buf, count, ppos, portinfo, | ||
| 292 | sizeof portinfo); | ||
| 293 | } | ||
| 294 | |||
| 295 | static struct file_operations atomic_port_info_ops = { | ||
| 296 | .read = atomic_port_info_read, | ||
| 297 | }; | ||
| 298 | |||
| 299 | static ssize_t flash_read(struct file *file, char __user *buf, | ||
| 300 | size_t count, loff_t *ppos) | ||
| 301 | { | ||
| 302 | struct ipath_devdata *dd; | ||
| 303 | ssize_t ret; | ||
| 304 | loff_t pos; | ||
| 305 | char *tmp; | ||
| 306 | |||
| 307 | pos = *ppos; | ||
| 308 | |||
| 309 | if ( pos < 0) { | ||
| 310 | ret = -EINVAL; | ||
| 311 | goto bail; | ||
| 312 | } | ||
| 313 | |||
| 314 | if (pos >= sizeof(struct ipath_flash)) { | ||
| 315 | ret = 0; | ||
| 316 | goto bail; | ||
| 317 | } | ||
| 318 | |||
| 319 | if (count > sizeof(struct ipath_flash) - pos) | ||
| 320 | count = sizeof(struct ipath_flash) - pos; | ||
| 321 | |||
| 322 | tmp = kmalloc(count, GFP_KERNEL); | ||
| 323 | if (!tmp) { | ||
| 324 | ret = -ENOMEM; | ||
| 325 | goto bail; | ||
| 326 | } | ||
| 327 | |||
| 328 | dd = file->f_dentry->d_inode->u.generic_ip; | ||
| 329 | if (ipath_eeprom_read(dd, pos, tmp, count)) { | ||
| 330 | ipath_dev_err(dd, "failed to read from flash\n"); | ||
| 331 | ret = -ENXIO; | ||
| 332 | goto bail_tmp; | ||
| 333 | } | ||
| 334 | |||
| 335 | if (copy_to_user(buf, tmp, count)) { | ||
| 336 | ret = -EFAULT; | ||
| 337 | goto bail_tmp; | ||
| 338 | } | ||
| 339 | |||
| 340 | *ppos = pos + count; | ||
| 341 | ret = count; | ||
| 342 | |||
| 343 | bail_tmp: | ||
| 344 | kfree(tmp); | ||
| 345 | |||
| 346 | bail: | ||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | static ssize_t flash_write(struct file *file, const char __user *buf, | ||
| 351 | size_t count, loff_t *ppos) | ||
| 352 | { | ||
| 353 | struct ipath_devdata *dd; | ||
| 354 | ssize_t ret; | ||
| 355 | loff_t pos; | ||
| 356 | char *tmp; | ||
| 357 | |||
| 358 | pos = *ppos; | ||
| 359 | |||
| 360 | if ( pos < 0) { | ||
| 361 | ret = -EINVAL; | ||
| 362 | goto bail; | ||
| 363 | } | ||
| 364 | |||
| 365 | if (pos >= sizeof(struct ipath_flash)) { | ||
| 366 | ret = 0; | ||
| 367 | goto bail; | ||
| 368 | } | ||
| 369 | |||
| 370 | if (count > sizeof(struct ipath_flash) - pos) | ||
| 371 | count = sizeof(struct ipath_flash) - pos; | ||
| 372 | |||
| 373 | tmp = kmalloc(count, GFP_KERNEL); | ||
| 374 | if (!tmp) { | ||
| 375 | ret = -ENOMEM; | ||
| 376 | goto bail; | ||
| 377 | } | ||
| 378 | |||
| 379 | if (copy_from_user(tmp, buf, count)) { | ||
| 380 | ret = -EFAULT; | ||
| 381 | goto bail_tmp; | ||
| 382 | } | ||
| 383 | |||
| 384 | dd = file->f_dentry->d_inode->u.generic_ip; | ||
| 385 | if (ipath_eeprom_write(dd, pos, tmp, count)) { | ||
| 386 | ret = -ENXIO; | ||
| 387 | ipath_dev_err(dd, "failed to write to flash\n"); | ||
| 388 | goto bail_tmp; | ||
| 389 | } | ||
| 390 | |||
| 391 | *ppos = pos + count; | ||
| 392 | ret = count; | ||
| 393 | |||
| 394 | bail_tmp: | ||
| 395 | kfree(tmp); | ||
| 396 | |||
| 397 | bail: | ||
| 398 | return ret; | ||
| 399 | } | ||
| 400 | |||
| 401 | static struct file_operations flash_ops = { | ||
| 402 | .read = flash_read, | ||
| 403 | .write = flash_write, | ||
| 404 | }; | ||
| 405 | |||
| 406 | static int create_device_files(struct super_block *sb, | ||
| 407 | struct ipath_devdata *dd) | ||
| 408 | { | ||
| 409 | struct dentry *dir, *tmp; | ||
| 410 | char unit[10]; | ||
| 411 | int ret; | ||
| 412 | |||
| 413 | snprintf(unit, sizeof unit, "%02d", dd->ipath_unit); | ||
| 414 | ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir, | ||
| 415 | (struct file_operations *) &simple_dir_operations, | ||
| 416 | dd); | ||
| 417 | if (ret) { | ||
| 418 | printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret); | ||
| 419 | goto bail; | ||
| 420 | } | ||
| 421 | |||
| 422 | ret = create_file("atomic_counters", S_IFREG|S_IRUGO, dir, &tmp, | ||
| 423 | &atomic_counters_ops, dd); | ||
| 424 | if (ret) { | ||
| 425 | printk(KERN_ERR "create_file(%s/atomic_counters) " | ||
| 426 | "failed: %d\n", unit, ret); | ||
| 427 | goto bail; | ||
| 428 | } | ||
| 429 | |||
| 430 | ret = create_file("node_info", S_IFREG|S_IRUGO, dir, &tmp, | ||
| 431 | &atomic_node_info_ops, dd); | ||
| 432 | if (ret) { | ||
| 433 | printk(KERN_ERR "create_file(%s/node_info) " | ||
| 434 | "failed: %d\n", unit, ret); | ||
| 435 | goto bail; | ||
| 436 | } | ||
| 437 | |||
| 438 | ret = create_file("port_info", S_IFREG|S_IRUGO, dir, &tmp, | ||
| 439 | &atomic_port_info_ops, dd); | ||
| 440 | if (ret) { | ||
| 441 | printk(KERN_ERR "create_file(%s/port_info) " | ||
| 442 | "failed: %d\n", unit, ret); | ||
| 443 | goto bail; | ||
| 444 | } | ||
| 445 | |||
| 446 | ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp, | ||
| 447 | &flash_ops, dd); | ||
| 448 | if (ret) { | ||
| 449 | printk(KERN_ERR "create_file(%s/flash) " | ||
| 450 | "failed: %d\n", unit, ret); | ||
| 451 | goto bail; | ||
| 452 | } | ||
| 453 | |||
| 454 | bail: | ||
| 455 | return ret; | ||
| 456 | } | ||
| 457 | |||
| 458 | static void remove_file(struct dentry *parent, char *name) | ||
| 459 | { | ||
| 460 | struct dentry *tmp; | ||
| 461 | |||
| 462 | tmp = lookup_one_len(name, parent, strlen(name)); | ||
| 463 | |||
| 464 | spin_lock(&dcache_lock); | ||
| 465 | spin_lock(&tmp->d_lock); | ||
| 466 | if (!(d_unhashed(tmp) && tmp->d_inode)) { | ||
| 467 | dget_locked(tmp); | ||
| 468 | __d_drop(tmp); | ||
| 469 | spin_unlock(&tmp->d_lock); | ||
| 470 | spin_unlock(&dcache_lock); | ||
| 471 | simple_unlink(parent->d_inode, tmp); | ||
| 472 | } else { | ||
| 473 | spin_unlock(&tmp->d_lock); | ||
| 474 | spin_unlock(&dcache_lock); | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | static int remove_device_files(struct super_block *sb, | ||
| 479 | struct ipath_devdata *dd) | ||
| 480 | { | ||
| 481 | struct dentry *dir, *root; | ||
| 482 | char unit[10]; | ||
| 483 | int ret; | ||
| 484 | |||
| 485 | root = dget(sb->s_root); | ||
| 486 | mutex_lock(&root->d_inode->i_mutex); | ||
| 487 | snprintf(unit, sizeof unit, "%02d", dd->ipath_unit); | ||
| 488 | dir = lookup_one_len(unit, root, strlen(unit)); | ||
| 489 | |||
| 490 | if (IS_ERR(dir)) { | ||
| 491 | ret = PTR_ERR(dir); | ||
| 492 | printk(KERN_ERR "Lookup of %s failed\n", unit); | ||
| 493 | goto bail; | ||
| 494 | } | ||
| 495 | |||
| 496 | remove_file(dir, "flash"); | ||
| 497 | remove_file(dir, "port_info"); | ||
| 498 | remove_file(dir, "node_info"); | ||
| 499 | remove_file(dir, "atomic_counters"); | ||
| 500 | d_delete(dir); | ||
| 501 | ret = simple_rmdir(root->d_inode, dir); | ||
| 502 | |||
| 503 | bail: | ||
| 504 | mutex_unlock(&root->d_inode->i_mutex); | ||
| 505 | dput(root); | ||
| 506 | return ret; | ||
| 507 | } | ||
| 508 | |||
| 509 | static int ipathfs_fill_super(struct super_block *sb, void *data, | ||
| 510 | int silent) | ||
| 511 | { | ||
| 512 | struct ipath_devdata *dd, *tmp; | ||
| 513 | unsigned long flags; | ||
| 514 | int ret; | ||
| 515 | |||
| 516 | static struct tree_descr files[] = { | ||
| 517 | [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, | ||
| 518 | {""}, | ||
| 519 | }; | ||
| 520 | |||
| 521 | ret = simple_fill_super(sb, IPATHFS_MAGIC, files); | ||
| 522 | if (ret) { | ||
| 523 | printk(KERN_ERR "simple_fill_super failed: %d\n", ret); | ||
| 524 | goto bail; | ||
| 525 | } | ||
| 526 | |||
| 527 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 528 | |||
| 529 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 530 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 531 | ret = create_device_files(sb, dd); | ||
| 532 | if (ret) { | ||
| 533 | deactivate_super(sb); | ||
| 534 | goto bail; | ||
| 535 | } | ||
| 536 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 537 | } | ||
| 538 | |||
| 539 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 540 | |||
| 541 | bail: | ||
| 542 | return ret; | ||
| 543 | } | ||
| 544 | |||
| 545 | static struct super_block *ipathfs_get_sb(struct file_system_type *fs_type, | ||
| 546 | int flags, const char *dev_name, | ||
| 547 | void *data) | ||
| 548 | { | ||
| 549 | ipath_super = get_sb_single(fs_type, flags, data, | ||
| 550 | ipathfs_fill_super); | ||
| 551 | return ipath_super; | ||
| 552 | } | ||
| 553 | |||
| 554 | static void ipathfs_kill_super(struct super_block *s) | ||
| 555 | { | ||
| 556 | kill_litter_super(s); | ||
| 557 | ipath_super = NULL; | ||
| 558 | } | ||
| 559 | |||
| 560 | int ipathfs_add_device(struct ipath_devdata *dd) | ||
| 561 | { | ||
| 562 | int ret; | ||
| 563 | |||
| 564 | if (ipath_super == NULL) { | ||
| 565 | ret = 0; | ||
| 566 | goto bail; | ||
| 567 | } | ||
| 568 | |||
| 569 | ret = create_device_files(ipath_super, dd); | ||
| 570 | |||
| 571 | bail: | ||
| 572 | return ret; | ||
| 573 | } | ||
| 574 | |||
| 575 | int ipathfs_remove_device(struct ipath_devdata *dd) | ||
| 576 | { | ||
| 577 | int ret; | ||
| 578 | |||
| 579 | if (ipath_super == NULL) { | ||
| 580 | ret = 0; | ||
| 581 | goto bail; | ||
| 582 | } | ||
| 583 | |||
| 584 | ret = remove_device_files(ipath_super, dd); | ||
| 585 | |||
| 586 | bail: | ||
| 587 | return ret; | ||
| 588 | } | ||
| 589 | |||
| 590 | static struct file_system_type ipathfs_fs_type = { | ||
| 591 | .owner = THIS_MODULE, | ||
| 592 | .name = "ipathfs", | ||
| 593 | .get_sb = ipathfs_get_sb, | ||
| 594 | .kill_sb = ipathfs_kill_super, | ||
| 595 | }; | ||
| 596 | |||
| 597 | int __init ipath_init_ipathfs(void) | ||
| 598 | { | ||
| 599 | return register_filesystem(&ipathfs_fs_type); | ||
| 600 | } | ||
| 601 | |||
| 602 | void __exit ipath_exit_ipathfs(void) | ||
| 603 | { | ||
| 604 | unregister_filesystem(&ipathfs_fs_type); | ||
| 605 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_ht400.c b/drivers/infiniband/hw/ipath/ipath_ht400.c new file mode 100644 index 000000000000..4652435998f3 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_ht400.c | |||
| @@ -0,0 +1,1586 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* | ||
| 34 | * This file contains all of the code that is specific to the InfiniPath | ||
| 35 | * HT-400 chip. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include <linux/pci.h> | ||
| 39 | #include <linux/delay.h> | ||
| 40 | |||
| 41 | #include "ipath_kernel.h" | ||
| 42 | #include "ipath_registers.h" | ||
| 43 | |||
| 44 | /* | ||
| 45 | * This lists the InfiniPath HT400 registers, in the actual chip layout. | ||
| 46 | * This structure should never be directly accessed. | ||
| 47 | * | ||
| 48 | * The names are in InterCap form because they're taken straight from | ||
| 49 | * the chip specification. Since they're only used in this file, they | ||
| 50 | * don't pollute the rest of the source. | ||
| 51 | */ | ||
| 52 | |||
| 53 | struct _infinipath_do_not_use_kernel_regs { | ||
| 54 | unsigned long long Revision; | ||
| 55 | unsigned long long Control; | ||
| 56 | unsigned long long PageAlign; | ||
| 57 | unsigned long long PortCnt; | ||
| 58 | unsigned long long DebugPortSelect; | ||
| 59 | unsigned long long DebugPort; | ||
| 60 | unsigned long long SendRegBase; | ||
| 61 | unsigned long long UserRegBase; | ||
| 62 | unsigned long long CounterRegBase; | ||
| 63 | unsigned long long Scratch; | ||
| 64 | unsigned long long ReservedMisc1; | ||
| 65 | unsigned long long InterruptConfig; | ||
| 66 | unsigned long long IntBlocked; | ||
| 67 | unsigned long long IntMask; | ||
| 68 | unsigned long long IntStatus; | ||
| 69 | unsigned long long IntClear; | ||
| 70 | unsigned long long ErrorMask; | ||
| 71 | unsigned long long ErrorStatus; | ||
| 72 | unsigned long long ErrorClear; | ||
| 73 | unsigned long long HwErrMask; | ||
| 74 | unsigned long long HwErrStatus; | ||
| 75 | unsigned long long HwErrClear; | ||
| 76 | unsigned long long HwDiagCtrl; | ||
| 77 | unsigned long long MDIO; | ||
| 78 | unsigned long long IBCStatus; | ||
| 79 | unsigned long long IBCCtrl; | ||
| 80 | unsigned long long ExtStatus; | ||
| 81 | unsigned long long ExtCtrl; | ||
| 82 | unsigned long long GPIOOut; | ||
| 83 | unsigned long long GPIOMask; | ||
| 84 | unsigned long long GPIOStatus; | ||
| 85 | unsigned long long GPIOClear; | ||
| 86 | unsigned long long RcvCtrl; | ||
| 87 | unsigned long long RcvBTHQP; | ||
| 88 | unsigned long long RcvHdrSize; | ||
| 89 | unsigned long long RcvHdrCnt; | ||
| 90 | unsigned long long RcvHdrEntSize; | ||
| 91 | unsigned long long RcvTIDBase; | ||
| 92 | unsigned long long RcvTIDCnt; | ||
| 93 | unsigned long long RcvEgrBase; | ||
| 94 | unsigned long long RcvEgrCnt; | ||
| 95 | unsigned long long RcvBufBase; | ||
| 96 | unsigned long long RcvBufSize; | ||
| 97 | unsigned long long RxIntMemBase; | ||
| 98 | unsigned long long RxIntMemSize; | ||
| 99 | unsigned long long RcvPartitionKey; | ||
| 100 | unsigned long long ReservedRcv[10]; | ||
| 101 | unsigned long long SendCtrl; | ||
| 102 | unsigned long long SendPIOBufBase; | ||
| 103 | unsigned long long SendPIOSize; | ||
| 104 | unsigned long long SendPIOBufCnt; | ||
| 105 | unsigned long long SendPIOAvailAddr; | ||
| 106 | unsigned long long TxIntMemBase; | ||
| 107 | unsigned long long TxIntMemSize; | ||
| 108 | unsigned long long ReservedSend[9]; | ||
| 109 | unsigned long long SendBufferError; | ||
| 110 | unsigned long long SendBufferErrorCONT1; | ||
| 111 | unsigned long long SendBufferErrorCONT2; | ||
| 112 | unsigned long long SendBufferErrorCONT3; | ||
| 113 | unsigned long long ReservedSBE[4]; | ||
| 114 | unsigned long long RcvHdrAddr0; | ||
| 115 | unsigned long long RcvHdrAddr1; | ||
| 116 | unsigned long long RcvHdrAddr2; | ||
| 117 | unsigned long long RcvHdrAddr3; | ||
| 118 | unsigned long long RcvHdrAddr4; | ||
| 119 | unsigned long long RcvHdrAddr5; | ||
| 120 | unsigned long long RcvHdrAddr6; | ||
| 121 | unsigned long long RcvHdrAddr7; | ||
| 122 | unsigned long long RcvHdrAddr8; | ||
| 123 | unsigned long long ReservedRHA[7]; | ||
| 124 | unsigned long long RcvHdrTailAddr0; | ||
| 125 | unsigned long long RcvHdrTailAddr1; | ||
| 126 | unsigned long long RcvHdrTailAddr2; | ||
| 127 | unsigned long long RcvHdrTailAddr3; | ||
| 128 | unsigned long long RcvHdrTailAddr4; | ||
| 129 | unsigned long long RcvHdrTailAddr5; | ||
| 130 | unsigned long long RcvHdrTailAddr6; | ||
| 131 | unsigned long long RcvHdrTailAddr7; | ||
| 132 | unsigned long long RcvHdrTailAddr8; | ||
| 133 | unsigned long long ReservedRHTA[7]; | ||
| 134 | unsigned long long Sync; /* Software only */ | ||
| 135 | unsigned long long Dump; /* Software only */ | ||
| 136 | unsigned long long SimVer; /* Software only */ | ||
| 137 | unsigned long long ReservedSW[5]; | ||
| 138 | unsigned long long SerdesConfig0; | ||
| 139 | unsigned long long SerdesConfig1; | ||
| 140 | unsigned long long SerdesStatus; | ||
| 141 | unsigned long long XGXSConfig; | ||
| 142 | unsigned long long ReservedSW2[4]; | ||
| 143 | }; | ||
| 144 | |||
| 145 | #define IPATH_KREG_OFFSET(field) (offsetof(struct \ | ||
| 146 | _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | ||
| 147 | #define IPATH_CREG_OFFSET(field) (offsetof( \ | ||
| 148 | struct infinipath_counters, field) / sizeof(u64)) | ||
| 149 | |||
| 150 | static const struct ipath_kregs ipath_ht_kregs = { | ||
| 151 | .kr_control = IPATH_KREG_OFFSET(Control), | ||
| 152 | .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), | ||
| 153 | .kr_debugport = IPATH_KREG_OFFSET(DebugPort), | ||
| 154 | .kr_debugportselect = IPATH_KREG_OFFSET(DebugPortSelect), | ||
| 155 | .kr_errorclear = IPATH_KREG_OFFSET(ErrorClear), | ||
| 156 | .kr_errormask = IPATH_KREG_OFFSET(ErrorMask), | ||
| 157 | .kr_errorstatus = IPATH_KREG_OFFSET(ErrorStatus), | ||
| 158 | .kr_extctrl = IPATH_KREG_OFFSET(ExtCtrl), | ||
| 159 | .kr_extstatus = IPATH_KREG_OFFSET(ExtStatus), | ||
| 160 | .kr_gpio_clear = IPATH_KREG_OFFSET(GPIOClear), | ||
| 161 | .kr_gpio_mask = IPATH_KREG_OFFSET(GPIOMask), | ||
| 162 | .kr_gpio_out = IPATH_KREG_OFFSET(GPIOOut), | ||
| 163 | .kr_gpio_status = IPATH_KREG_OFFSET(GPIOStatus), | ||
| 164 | .kr_hwdiagctrl = IPATH_KREG_OFFSET(HwDiagCtrl), | ||
| 165 | .kr_hwerrclear = IPATH_KREG_OFFSET(HwErrClear), | ||
| 166 | .kr_hwerrmask = IPATH_KREG_OFFSET(HwErrMask), | ||
| 167 | .kr_hwerrstatus = IPATH_KREG_OFFSET(HwErrStatus), | ||
| 168 | .kr_ibcctrl = IPATH_KREG_OFFSET(IBCCtrl), | ||
| 169 | .kr_ibcstatus = IPATH_KREG_OFFSET(IBCStatus), | ||
| 170 | .kr_intblocked = IPATH_KREG_OFFSET(IntBlocked), | ||
| 171 | .kr_intclear = IPATH_KREG_OFFSET(IntClear), | ||
| 172 | .kr_interruptconfig = IPATH_KREG_OFFSET(InterruptConfig), | ||
| 173 | .kr_intmask = IPATH_KREG_OFFSET(IntMask), | ||
| 174 | .kr_intstatus = IPATH_KREG_OFFSET(IntStatus), | ||
| 175 | .kr_mdio = IPATH_KREG_OFFSET(MDIO), | ||
| 176 | .kr_pagealign = IPATH_KREG_OFFSET(PageAlign), | ||
| 177 | .kr_partitionkey = IPATH_KREG_OFFSET(RcvPartitionKey), | ||
| 178 | .kr_portcnt = IPATH_KREG_OFFSET(PortCnt), | ||
| 179 | .kr_rcvbthqp = IPATH_KREG_OFFSET(RcvBTHQP), | ||
| 180 | .kr_rcvbufbase = IPATH_KREG_OFFSET(RcvBufBase), | ||
| 181 | .kr_rcvbufsize = IPATH_KREG_OFFSET(RcvBufSize), | ||
| 182 | .kr_rcvctrl = IPATH_KREG_OFFSET(RcvCtrl), | ||
| 183 | .kr_rcvegrbase = IPATH_KREG_OFFSET(RcvEgrBase), | ||
| 184 | .kr_rcvegrcnt = IPATH_KREG_OFFSET(RcvEgrCnt), | ||
| 185 | .kr_rcvhdrcnt = IPATH_KREG_OFFSET(RcvHdrCnt), | ||
| 186 | .kr_rcvhdrentsize = IPATH_KREG_OFFSET(RcvHdrEntSize), | ||
| 187 | .kr_rcvhdrsize = IPATH_KREG_OFFSET(RcvHdrSize), | ||
| 188 | .kr_rcvintmembase = IPATH_KREG_OFFSET(RxIntMemBase), | ||
| 189 | .kr_rcvintmemsize = IPATH_KREG_OFFSET(RxIntMemSize), | ||
| 190 | .kr_rcvtidbase = IPATH_KREG_OFFSET(RcvTIDBase), | ||
| 191 | .kr_rcvtidcnt = IPATH_KREG_OFFSET(RcvTIDCnt), | ||
| 192 | .kr_revision = IPATH_KREG_OFFSET(Revision), | ||
| 193 | .kr_scratch = IPATH_KREG_OFFSET(Scratch), | ||
| 194 | .kr_sendbuffererror = IPATH_KREG_OFFSET(SendBufferError), | ||
| 195 | .kr_sendctrl = IPATH_KREG_OFFSET(SendCtrl), | ||
| 196 | .kr_sendpioavailaddr = IPATH_KREG_OFFSET(SendPIOAvailAddr), | ||
| 197 | .kr_sendpiobufbase = IPATH_KREG_OFFSET(SendPIOBufBase), | ||
| 198 | .kr_sendpiobufcnt = IPATH_KREG_OFFSET(SendPIOBufCnt), | ||
| 199 | .kr_sendpiosize = IPATH_KREG_OFFSET(SendPIOSize), | ||
| 200 | .kr_sendregbase = IPATH_KREG_OFFSET(SendRegBase), | ||
| 201 | .kr_txintmembase = IPATH_KREG_OFFSET(TxIntMemBase), | ||
| 202 | .kr_txintmemsize = IPATH_KREG_OFFSET(TxIntMemSize), | ||
| 203 | .kr_userregbase = IPATH_KREG_OFFSET(UserRegBase), | ||
| 204 | .kr_serdesconfig0 = IPATH_KREG_OFFSET(SerdesConfig0), | ||
| 205 | .kr_serdesconfig1 = IPATH_KREG_OFFSET(SerdesConfig1), | ||
| 206 | .kr_serdesstatus = IPATH_KREG_OFFSET(SerdesStatus), | ||
| 207 | .kr_xgxsconfig = IPATH_KREG_OFFSET(XGXSConfig), | ||
| 208 | /* | ||
| 209 | * These should not be used directly via ipath_read_kreg64(), | ||
| 210 | * use them with ipath_read_kreg64_port(), | ||
| 211 | */ | ||
| 212 | .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), | ||
| 213 | .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0) | ||
| 214 | }; | ||
| 215 | |||
| 216 | static const struct ipath_cregs ipath_ht_cregs = { | ||
| 217 | .cr_badformatcnt = IPATH_CREG_OFFSET(RxBadFormatCnt), | ||
| 218 | .cr_erricrccnt = IPATH_CREG_OFFSET(RxICRCErrCnt), | ||
| 219 | .cr_errlinkcnt = IPATH_CREG_OFFSET(RxLinkProblemCnt), | ||
| 220 | .cr_errlpcrccnt = IPATH_CREG_OFFSET(RxLPCRCErrCnt), | ||
| 221 | .cr_errpkey = IPATH_CREG_OFFSET(RxPKeyMismatchCnt), | ||
| 222 | .cr_errrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowCtrlErrCnt), | ||
| 223 | .cr_err_rlencnt = IPATH_CREG_OFFSET(RxLenErrCnt), | ||
| 224 | .cr_errslencnt = IPATH_CREG_OFFSET(TxLenErrCnt), | ||
| 225 | .cr_errtidfull = IPATH_CREG_OFFSET(RxTIDFullErrCnt), | ||
| 226 | .cr_errtidvalid = IPATH_CREG_OFFSET(RxTIDValidErrCnt), | ||
| 227 | .cr_errvcrccnt = IPATH_CREG_OFFSET(RxVCRCErrCnt), | ||
| 228 | .cr_ibstatuschange = IPATH_CREG_OFFSET(IBStatusChangeCnt), | ||
| 229 | /* calc from Reg_CounterRegBase + offset */ | ||
| 230 | .cr_intcnt = IPATH_CREG_OFFSET(LBIntCnt), | ||
| 231 | .cr_invalidrlencnt = IPATH_CREG_OFFSET(RxMaxMinLenErrCnt), | ||
| 232 | .cr_invalidslencnt = IPATH_CREG_OFFSET(TxMaxMinLenErrCnt), | ||
| 233 | .cr_lbflowstallcnt = IPATH_CREG_OFFSET(LBFlowStallCnt), | ||
| 234 | .cr_pktrcvcnt = IPATH_CREG_OFFSET(RxDataPktCnt), | ||
| 235 | .cr_pktrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowPktCnt), | ||
| 236 | .cr_pktsendcnt = IPATH_CREG_OFFSET(TxDataPktCnt), | ||
| 237 | .cr_pktsendflowcnt = IPATH_CREG_OFFSET(TxFlowPktCnt), | ||
| 238 | .cr_portovflcnt = IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt), | ||
| 239 | .cr_rcvebpcnt = IPATH_CREG_OFFSET(RxEBPCnt), | ||
| 240 | .cr_rcvovflcnt = IPATH_CREG_OFFSET(RxBufOvflCnt), | ||
| 241 | .cr_senddropped = IPATH_CREG_OFFSET(TxDroppedPktCnt), | ||
| 242 | .cr_sendstallcnt = IPATH_CREG_OFFSET(TxFlowStallCnt), | ||
| 243 | .cr_sendunderruncnt = IPATH_CREG_OFFSET(TxUnderrunCnt), | ||
| 244 | .cr_wordrcvcnt = IPATH_CREG_OFFSET(RxDwordCnt), | ||
| 245 | .cr_wordsendcnt = IPATH_CREG_OFFSET(TxDwordCnt), | ||
| 246 | .cr_unsupvlcnt = IPATH_CREG_OFFSET(TxUnsupVLErrCnt), | ||
| 247 | .cr_rxdroppktcnt = IPATH_CREG_OFFSET(RxDroppedPktCnt), | ||
| 248 | .cr_iblinkerrrecovcnt = IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt), | ||
| 249 | .cr_iblinkdowncnt = IPATH_CREG_OFFSET(IBLinkDownedCnt), | ||
| 250 | .cr_ibsymbolerrcnt = IPATH_CREG_OFFSET(IBSymbolErrCnt) | ||
| 251 | }; | ||
| 252 | |||
| 253 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | ||
| 254 | #define INFINIPATH_I_RCVURG_MASK 0x1FF | ||
| 255 | #define INFINIPATH_I_RCVAVAIL_MASK 0x1FF | ||
| 256 | |||
| 257 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ | ||
| 258 | #define INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT 0 | ||
| 259 | #define INFINIPATH_HWE_HTCMEMPARITYERR_MASK 0x3FFFFFULL | ||
| 260 | #define INFINIPATH_HWE_HTCLNKABYTE0CRCERR 0x0000000000800000ULL | ||
| 261 | #define INFINIPATH_HWE_HTCLNKABYTE1CRCERR 0x0000000001000000ULL | ||
| 262 | #define INFINIPATH_HWE_HTCLNKBBYTE0CRCERR 0x0000000002000000ULL | ||
| 263 | #define INFINIPATH_HWE_HTCLNKBBYTE1CRCERR 0x0000000004000000ULL | ||
| 264 | #define INFINIPATH_HWE_HTCMISCERR4 0x0000000008000000ULL | ||
| 265 | #define INFINIPATH_HWE_HTCMISCERR5 0x0000000010000000ULL | ||
| 266 | #define INFINIPATH_HWE_HTCMISCERR6 0x0000000020000000ULL | ||
| 267 | #define INFINIPATH_HWE_HTCMISCERR7 0x0000000040000000ULL | ||
| 268 | #define INFINIPATH_HWE_HTCBUSTREQPARITYERR 0x0000000080000000ULL | ||
| 269 | #define INFINIPATH_HWE_HTCBUSTRESPPARITYERR 0x0000000100000000ULL | ||
| 270 | #define INFINIPATH_HWE_HTCBUSIREQPARITYERR 0x0000000200000000ULL | ||
| 271 | #define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL | ||
| 272 | #define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL | ||
| 273 | #define INFINIPATH_HWE_HTBPLL_FBSLIP 0x0200000000000000ULL | ||
| 274 | #define INFINIPATH_HWE_HTBPLL_RFSLIP 0x0400000000000000ULL | ||
| 275 | #define INFINIPATH_HWE_HTAPLL_FBSLIP 0x0800000000000000ULL | ||
| 276 | #define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL | ||
| 277 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL | ||
| 278 | |||
| 279 | /* kr_extstatus bits */ | ||
| 280 | #define INFINIPATH_EXTS_FREQSEL 0x2 | ||
| 281 | #define INFINIPATH_EXTS_SERDESSEL 0x4 | ||
| 282 | #define INFINIPATH_EXTS_MEMBIST_ENDTEST 0x0000000000004000 | ||
| 283 | #define INFINIPATH_EXTS_MEMBIST_CORRECT 0x0000000000008000 | ||
| 284 | |||
| 285 | /* | ||
| 286 | * masks and bits that are different in different chips, or present only | ||
| 287 | * in one | ||
| 288 | */ | ||
| 289 | static const ipath_err_t infinipath_hwe_htcmemparityerr_mask = | ||
| 290 | INFINIPATH_HWE_HTCMEMPARITYERR_MASK; | ||
| 291 | static const ipath_err_t infinipath_hwe_htcmemparityerr_shift = | ||
| 292 | INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT; | ||
| 293 | |||
| 294 | static const ipath_err_t infinipath_hwe_htclnkabyte0crcerr = | ||
| 295 | INFINIPATH_HWE_HTCLNKABYTE0CRCERR; | ||
| 296 | static const ipath_err_t infinipath_hwe_htclnkabyte1crcerr = | ||
| 297 | INFINIPATH_HWE_HTCLNKABYTE1CRCERR; | ||
| 298 | static const ipath_err_t infinipath_hwe_htclnkbbyte0crcerr = | ||
| 299 | INFINIPATH_HWE_HTCLNKBBYTE0CRCERR; | ||
| 300 | static const ipath_err_t infinipath_hwe_htclnkbbyte1crcerr = | ||
| 301 | INFINIPATH_HWE_HTCLNKBBYTE1CRCERR; | ||
| 302 | |||
| 303 | #define _IPATH_GPIO_SDA_NUM 1 | ||
| 304 | #define _IPATH_GPIO_SCL_NUM 0 | ||
| 305 | |||
| 306 | #define IPATH_GPIO_SDA \ | ||
| 307 | (1ULL << (_IPATH_GPIO_SDA_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) | ||
| 308 | #define IPATH_GPIO_SCL \ | ||
| 309 | (1ULL << (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) | ||
| 310 | |||
| 311 | /* keep the code below somewhat more readonable; not used elsewhere */ | ||
| 312 | #define _IPATH_HTLINK0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr | \ | ||
| 313 | infinipath_hwe_htclnkabyte1crcerr) | ||
| 314 | #define _IPATH_HTLINK1_CRCBITS (infinipath_hwe_htclnkbbyte0crcerr | \ | ||
| 315 | infinipath_hwe_htclnkbbyte1crcerr) | ||
| 316 | #define _IPATH_HTLANE0_CRCBITS (infinipath_hwe_htclnkabyte0crcerr | \ | ||
| 317 | infinipath_hwe_htclnkbbyte0crcerr) | ||
| 318 | #define _IPATH_HTLANE1_CRCBITS (infinipath_hwe_htclnkabyte1crcerr | \ | ||
| 319 | infinipath_hwe_htclnkbbyte1crcerr) | ||
| 320 | |||
| 321 | static void hwerr_crcbits(struct ipath_devdata *dd, ipath_err_t hwerrs, | ||
| 322 | char *msg, size_t msgl) | ||
| 323 | { | ||
| 324 | char bitsmsg[64]; | ||
| 325 | ipath_err_t crcbits = hwerrs & | ||
| 326 | (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS); | ||
| 327 | /* don't check if 8bit HT */ | ||
| 328 | if (dd->ipath_flags & IPATH_8BIT_IN_HT0) | ||
| 329 | crcbits &= ~infinipath_hwe_htclnkabyte1crcerr; | ||
| 330 | /* don't check if 8bit HT */ | ||
| 331 | if (dd->ipath_flags & IPATH_8BIT_IN_HT1) | ||
| 332 | crcbits &= ~infinipath_hwe_htclnkbbyte1crcerr; | ||
| 333 | /* | ||
| 334 | * we'll want to ignore link errors on link that is | ||
| 335 | * not in use, if any. For now, complain about both | ||
| 336 | */ | ||
| 337 | if (crcbits) { | ||
| 338 | u16 ctrl0, ctrl1; | ||
| 339 | snprintf(bitsmsg, sizeof bitsmsg, | ||
| 340 | "[HT%s lane %s CRC (%llx); ignore till reload]", | ||
| 341 | !(crcbits & _IPATH_HTLINK1_CRCBITS) ? | ||
| 342 | "0 (A)" : (!(crcbits & _IPATH_HTLINK0_CRCBITS) | ||
| 343 | ? "1 (B)" : "0+1 (A+B)"), | ||
| 344 | !(crcbits & _IPATH_HTLANE1_CRCBITS) ? "0" | ||
| 345 | : (!(crcbits & _IPATH_HTLANE0_CRCBITS) ? "1" : | ||
| 346 | "0+1"), (unsigned long long) crcbits); | ||
| 347 | strlcat(msg, bitsmsg, msgl); | ||
| 348 | |||
| 349 | /* | ||
| 350 | * print extra info for debugging. slave/primary | ||
| 351 | * config word 4, 8 (link control 0, 1) | ||
| 352 | */ | ||
| 353 | |||
| 354 | if (pci_read_config_word(dd->pcidev, | ||
| 355 | dd->ipath_ht_slave_off + 0x4, | ||
| 356 | &ctrl0)) | ||
| 357 | dev_info(&dd->pcidev->dev, "Couldn't read " | ||
| 358 | "linkctrl0 of slave/primary " | ||
| 359 | "config block\n"); | ||
| 360 | else if (!(ctrl0 & 1 << 6)) | ||
| 361 | /* not if EOC bit set */ | ||
| 362 | ipath_dbg("HT linkctrl0 0x%x%s%s\n", ctrl0, | ||
| 363 | ((ctrl0 >> 8) & 7) ? " CRC" : "", | ||
| 364 | ((ctrl0 >> 4) & 1) ? "linkfail" : | ||
| 365 | ""); | ||
| 366 | if (pci_read_config_word(dd->pcidev, | ||
| 367 | dd->ipath_ht_slave_off + 0x8, | ||
| 368 | &ctrl1)) | ||
| 369 | dev_info(&dd->pcidev->dev, "Couldn't read " | ||
| 370 | "linkctrl1 of slave/primary " | ||
| 371 | "config block\n"); | ||
| 372 | else if (!(ctrl1 & 1 << 6)) | ||
| 373 | /* not if EOC bit set */ | ||
| 374 | ipath_dbg("HT linkctrl1 0x%x%s%s\n", ctrl1, | ||
| 375 | ((ctrl1 >> 8) & 7) ? " CRC" : "", | ||
| 376 | ((ctrl1 >> 4) & 1) ? "linkfail" : | ||
| 377 | ""); | ||
| 378 | |||
| 379 | /* disable until driver reloaded */ | ||
| 380 | dd->ipath_hwerrmask &= ~crcbits; | ||
| 381 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 382 | dd->ipath_hwerrmask); | ||
| 383 | ipath_dbg("HT crc errs: %s\n", msg); | ||
| 384 | } else | ||
| 385 | ipath_dbg("ignoring HT crc errors 0x%llx, " | ||
| 386 | "not in use\n", (unsigned long long) | ||
| 387 | (hwerrs & (_IPATH_HTLINK0_CRCBITS | | ||
| 388 | _IPATH_HTLINK1_CRCBITS))); | ||
| 389 | } | ||
| 390 | |||
| 391 | /** | ||
| 392 | * ipath_ht_handle_hwerrors - display hardware errors | ||
| 393 | * @dd: the infinipath device | ||
| 394 | * @msg: the output buffer | ||
| 395 | * @msgl: the size of the output buffer | ||
| 396 | * | ||
| 397 | * Use same msg buffer as regular errors to avoid | ||
| 398 | * excessive stack use. Most hardware errors are catastrophic, but for | ||
| 399 | * right now, we'll print them and continue. | ||
| 400 | * We reuse the same message buffer as ipath_handle_errors() to avoid | ||
| 401 | * excessive stack usage. | ||
| 402 | */ | ||
| 403 | static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg, | ||
| 404 | size_t msgl) | ||
| 405 | { | ||
| 406 | ipath_err_t hwerrs; | ||
| 407 | u32 bits, ctrl; | ||
| 408 | int isfatal = 0; | ||
| 409 | char bitsmsg[64]; | ||
| 410 | |||
| 411 | hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); | ||
| 412 | |||
| 413 | if (!hwerrs) { | ||
| 414 | ipath_cdbg(VERBOSE, "Called but no hardware errors set\n"); | ||
| 415 | /* | ||
| 416 | * better than printing cofusing messages | ||
| 417 | * This seems to be related to clearing the crc error, or | ||
| 418 | * the pll error during init. | ||
| 419 | */ | ||
| 420 | goto bail; | ||
| 421 | } else if (hwerrs == -1LL) { | ||
| 422 | ipath_dev_err(dd, "Read of hardware error status failed " | ||
| 423 | "(all bits set); ignoring\n"); | ||
| 424 | goto bail; | ||
| 425 | } | ||
| 426 | ipath_stats.sps_hwerrs++; | ||
| 427 | |||
| 428 | /* Always clear the error status register, except MEMBISTFAIL, | ||
| 429 | * regardless of whether we continue or stop using the chip. | ||
| 430 | * We want that set so we know it failed, even across driver reload. | ||
| 431 | * We'll still ignore it in the hwerrmask. We do this partly for | ||
| 432 | * diagnostics, but also for support */ | ||
| 433 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 434 | hwerrs&~INFINIPATH_HWE_MEMBISTFAILED); | ||
| 435 | |||
| 436 | hwerrs &= dd->ipath_hwerrmask; | ||
| 437 | |||
| 438 | /* | ||
| 439 | * make sure we get this much out, unless told to be quiet, | ||
| 440 | * or it's occurred within the last 5 seconds | ||
| 441 | */ | ||
| 442 | if ((hwerrs & ~dd->ipath_lasthwerror) || | ||
| 443 | (ipath_debug & __IPATH_VERBDBG)) | ||
| 444 | dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " | ||
| 445 | "(cleared)\n", (unsigned long long) hwerrs); | ||
| 446 | dd->ipath_lasthwerror |= hwerrs; | ||
| 447 | |||
| 448 | if (hwerrs & ~infinipath_hwe_bitsextant) | ||
| 449 | ipath_dev_err(dd, "hwerror interrupt with unknown errors " | ||
| 450 | "%llx set\n", (unsigned long long) | ||
| 451 | (hwerrs & ~infinipath_hwe_bitsextant)); | ||
| 452 | |||
| 453 | ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); | ||
| 454 | if (ctrl & INFINIPATH_C_FREEZEMODE) { | ||
| 455 | if (hwerrs) { | ||
| 456 | /* | ||
| 457 | * if any set that we aren't ignoring; only | ||
| 458 | * make the complaint once, in case it's stuck | ||
| 459 | * or recurring, and we get here multiple | ||
| 460 | * times. | ||
| 461 | */ | ||
| 462 | if (dd->ipath_flags & IPATH_INITTED) { | ||
| 463 | ipath_dev_err(dd, "Fatal Error (freeze " | ||
| 464 | "mode), no longer usable\n"); | ||
| 465 | isfatal = 1; | ||
| 466 | } | ||
| 467 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; | ||
| 468 | /* mark as having had error */ | ||
| 469 | *dd->ipath_statusp |= IPATH_STATUS_HWERROR; | ||
| 470 | /* | ||
| 471 | * mark as not usable, at a minimum until driver | ||
| 472 | * is reloaded, probably until reboot, since no | ||
| 473 | * other reset is possible. | ||
| 474 | */ | ||
| 475 | dd->ipath_flags &= ~IPATH_INITTED; | ||
| 476 | } else { | ||
| 477 | ipath_dbg("Clearing freezemode on ignored hardware " | ||
| 478 | "error\n"); | ||
| 479 | ctrl &= ~INFINIPATH_C_FREEZEMODE; | ||
| 480 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 481 | ctrl); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | *msg = '\0'; | ||
| 486 | |||
| 487 | /* | ||
| 488 | * may someday want to decode into which bits are which | ||
| 489 | * functional area for parity errors, etc. | ||
| 490 | */ | ||
| 491 | if (hwerrs & (infinipath_hwe_htcmemparityerr_mask | ||
| 492 | << INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT)) { | ||
| 493 | bits = (u32) ((hwerrs >> | ||
| 494 | INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT) & | ||
| 495 | INFINIPATH_HWE_HTCMEMPARITYERR_MASK); | ||
| 496 | snprintf(bitsmsg, sizeof bitsmsg, "[HTC Parity Errs %x] ", | ||
| 497 | bits); | ||
| 498 | strlcat(msg, bitsmsg, msgl); | ||
| 499 | } | ||
| 500 | if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK | ||
| 501 | << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) { | ||
| 502 | bits = (u32) ((hwerrs >> | ||
| 503 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) & | ||
| 504 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK); | ||
| 505 | snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ", | ||
| 506 | bits); | ||
| 507 | strlcat(msg, bitsmsg, msgl); | ||
| 508 | } | ||
| 509 | if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK | ||
| 510 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) { | ||
| 511 | bits = (u32) ((hwerrs >> | ||
| 512 | INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) & | ||
| 513 | INFINIPATH_HWE_TXEMEMPARITYERR_MASK); | ||
| 514 | snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ", | ||
| 515 | bits); | ||
| 516 | strlcat(msg, bitsmsg, msgl); | ||
| 517 | } | ||
| 518 | if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR) | ||
| 519 | strlcat(msg, "[IB2IPATH Parity]", msgl); | ||
| 520 | if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR) | ||
| 521 | strlcat(msg, "[IPATH2IB Parity]", msgl); | ||
| 522 | if (hwerrs & INFINIPATH_HWE_HTCBUSIREQPARITYERR) | ||
| 523 | strlcat(msg, "[HTC Ireq Parity]", msgl); | ||
| 524 | if (hwerrs & INFINIPATH_HWE_HTCBUSTREQPARITYERR) | ||
| 525 | strlcat(msg, "[HTC Treq Parity]", msgl); | ||
| 526 | if (hwerrs & INFINIPATH_HWE_HTCBUSTRESPPARITYERR) | ||
| 527 | strlcat(msg, "[HTC Tresp Parity]", msgl); | ||
| 528 | |||
| 529 | if (hwerrs & (_IPATH_HTLINK0_CRCBITS | _IPATH_HTLINK1_CRCBITS)) | ||
| 530 | hwerr_crcbits(dd, hwerrs, msg, msgl); | ||
| 531 | |||
| 532 | if (hwerrs & INFINIPATH_HWE_HTCMISCERR5) | ||
| 533 | strlcat(msg, "[HT core Misc5]", msgl); | ||
| 534 | if (hwerrs & INFINIPATH_HWE_HTCMISCERR6) | ||
| 535 | strlcat(msg, "[HT core Misc6]", msgl); | ||
| 536 | if (hwerrs & INFINIPATH_HWE_HTCMISCERR7) | ||
| 537 | strlcat(msg, "[HT core Misc7]", msgl); | ||
| 538 | if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { | ||
| 539 | strlcat(msg, "[Memory BIST test failed, HT-400 unusable]", | ||
| 540 | msgl); | ||
| 541 | /* ignore from now on, so disable until driver reloaded */ | ||
| 542 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED; | ||
| 543 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 544 | dd->ipath_hwerrmask); | ||
| 545 | } | ||
| 546 | #define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP | \ | ||
| 547 | INFINIPATH_HWE_COREPLL_RFSLIP | \ | ||
| 548 | INFINIPATH_HWE_HTBPLL_FBSLIP | \ | ||
| 549 | INFINIPATH_HWE_HTBPLL_RFSLIP | \ | ||
| 550 | INFINIPATH_HWE_HTAPLL_FBSLIP | \ | ||
| 551 | INFINIPATH_HWE_HTAPLL_RFSLIP) | ||
| 552 | |||
| 553 | if (hwerrs & _IPATH_PLL_FAIL) { | ||
| 554 | snprintf(bitsmsg, sizeof bitsmsg, | ||
| 555 | "[PLL failed (%llx), HT-400 unusable]", | ||
| 556 | (unsigned long long) (hwerrs & _IPATH_PLL_FAIL)); | ||
| 557 | strlcat(msg, bitsmsg, msgl); | ||
| 558 | /* ignore from now on, so disable until driver reloaded */ | ||
| 559 | dd->ipath_hwerrmask &= ~(hwerrs & _IPATH_PLL_FAIL); | ||
| 560 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 561 | dd->ipath_hwerrmask); | ||
| 562 | } | ||
| 563 | |||
| 564 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { | ||
| 565 | /* | ||
| 566 | * If it occurs, it is left masked since the eternal | ||
| 567 | * interface is unused | ||
| 568 | */ | ||
| 569 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; | ||
| 570 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 571 | dd->ipath_hwerrmask); | ||
| 572 | } | ||
| 573 | |||
| 574 | if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR) | ||
| 575 | strlcat(msg, "[Rx Dsync]", msgl); | ||
| 576 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) | ||
| 577 | strlcat(msg, "[SerDes PLL]", msgl); | ||
| 578 | |||
| 579 | ipath_dev_err(dd, "%s hardware error\n", msg); | ||
| 580 | if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) | ||
| 581 | /* | ||
| 582 | * for status file; if no trailing brace is copied, | ||
| 583 | * we'll know it was truncated. | ||
| 584 | */ | ||
| 585 | snprintf(dd->ipath_freezemsg, | ||
| 586 | dd->ipath_freezelen, "{%s}", msg); | ||
| 587 | |||
| 588 | bail:; | ||
| 589 | } | ||
| 590 | |||
| 591 | /** | ||
| 592 | * ipath_ht_boardname - fill in the board name | ||
| 593 | * @dd: the infinipath device | ||
| 594 | * @name: the output buffer | ||
| 595 | * @namelen: the size of the output buffer | ||
| 596 | * | ||
| 597 | * fill in the board name, based on the board revision register | ||
| 598 | */ | ||
| 599 | static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | ||
| 600 | size_t namelen) | ||
| 601 | { | ||
| 602 | char *n = NULL; | ||
| 603 | u8 boardrev = dd->ipath_boardrev; | ||
| 604 | int ret; | ||
| 605 | |||
| 606 | switch (boardrev) { | ||
| 607 | case 4: /* Ponderosa is one of the bringup boards */ | ||
| 608 | n = "Ponderosa"; | ||
| 609 | break; | ||
| 610 | case 5: /* HT-460 original production board */ | ||
| 611 | n = "InfiniPath_HT-460"; | ||
| 612 | break; | ||
| 613 | case 6: | ||
| 614 | n = "OEM_Board_3"; | ||
| 615 | break; | ||
| 616 | case 7: | ||
| 617 | /* HT-460 small form factor production board */ | ||
| 618 | n = "InfiniPath_HT-465"; | ||
| 619 | break; | ||
| 620 | case 8: | ||
| 621 | n = "LS/X-1"; | ||
| 622 | break; | ||
| 623 | case 9: /* Comstock bringup test board */ | ||
| 624 | n = "Comstock"; | ||
| 625 | break; | ||
| 626 | case 10: | ||
| 627 | n = "OEM_Board_2"; | ||
| 628 | break; | ||
| 629 | case 11: | ||
| 630 | n = "InfiniPath_HT-470"; | ||
| 631 | break; | ||
| 632 | case 12: | ||
| 633 | n = "OEM_Board_4"; | ||
| 634 | break; | ||
| 635 | default: /* don't know, just print the number */ | ||
| 636 | ipath_dev_err(dd, "Don't yet know about board " | ||
| 637 | "with ID %u\n", boardrev); | ||
| 638 | snprintf(name, namelen, "Unknown_InfiniPath_HT-4xx_%u", | ||
| 639 | boardrev); | ||
| 640 | break; | ||
| 641 | } | ||
| 642 | if (n) | ||
| 643 | snprintf(name, namelen, "%s", n); | ||
| 644 | |||
| 645 | if (dd->ipath_majrev != 3 || dd->ipath_minrev != 2) { | ||
| 646 | /* | ||
| 647 | * This version of the driver only supports the HT-400 | ||
| 648 | * Rev 3.2 | ||
| 649 | */ | ||
| 650 | ipath_dev_err(dd, | ||
| 651 | "Unsupported HT-400 revision %u.%u!\n", | ||
| 652 | dd->ipath_majrev, dd->ipath_minrev); | ||
| 653 | ret = 1; | ||
| 654 | goto bail; | ||
| 655 | } | ||
| 656 | /* | ||
| 657 | * pkt/word counters are 32 bit, and therefore wrap fast enough | ||
| 658 | * that we snapshot them from a timer, and maintain 64 bit shadow | ||
| 659 | * copies | ||
| 660 | */ | ||
| 661 | dd->ipath_flags |= IPATH_32BITCOUNTERS; | ||
| 662 | if (dd->ipath_htspeed != 800) | ||
| 663 | ipath_dev_err(dd, | ||
| 664 | "Incorrectly configured for HT @ %uMHz\n", | ||
| 665 | dd->ipath_htspeed); | ||
| 666 | if (dd->ipath_boardrev == 7 || dd->ipath_boardrev == 11 || | ||
| 667 | dd->ipath_boardrev == 6) | ||
| 668 | dd->ipath_flags |= IPATH_GPIO_INTR; | ||
| 669 | else | ||
| 670 | dd->ipath_flags |= IPATH_POLL_RX_INTR; | ||
| 671 | if (dd->ipath_boardrev == 8) { /* LS/X-1 */ | ||
| 672 | u64 val; | ||
| 673 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); | ||
| 674 | if (val & INFINIPATH_EXTS_SERDESSEL) { | ||
| 675 | /* | ||
| 676 | * hardware disabled | ||
| 677 | * | ||
| 678 | * This means that the chip is hardware disabled, | ||
| 679 | * and will not be able to bring up the link, | ||
| 680 | * in any case. We special case this and abort | ||
| 681 | * early, to avoid later messages. We also set | ||
| 682 | * the DISABLED status bit | ||
| 683 | */ | ||
| 684 | ipath_dbg("Unit %u is hardware-disabled\n", | ||
| 685 | dd->ipath_unit); | ||
| 686 | *dd->ipath_statusp |= IPATH_STATUS_DISABLED; | ||
| 687 | /* this value is handled differently */ | ||
| 688 | ret = 2; | ||
| 689 | goto bail; | ||
| 690 | } | ||
| 691 | } | ||
| 692 | ret = 0; | ||
| 693 | |||
| 694 | bail: | ||
| 695 | return ret; | ||
| 696 | } | ||
| 697 | |||
| 698 | static void ipath_check_htlink(struct ipath_devdata *dd) | ||
| 699 | { | ||
| 700 | u8 linkerr, link_off, i; | ||
| 701 | |||
| 702 | for (i = 0; i < 2; i++) { | ||
| 703 | link_off = dd->ipath_ht_slave_off + i * 4 + 0xd; | ||
| 704 | if (pci_read_config_byte(dd->pcidev, link_off, &linkerr)) | ||
| 705 | dev_info(&dd->pcidev->dev, "Couldn't read " | ||
| 706 | "linkerror%d of HT slave/primary block\n", | ||
| 707 | i); | ||
| 708 | else if (linkerr & 0xf0) { | ||
| 709 | ipath_cdbg(VERBOSE, "HT linkerr%d bits 0x%x set, " | ||
| 710 | "clearing\n", linkerr >> 4, i); | ||
| 711 | /* | ||
| 712 | * writing the linkerr bits that are set should | ||
| 713 | * clear them | ||
| 714 | */ | ||
| 715 | if (pci_write_config_byte(dd->pcidev, link_off, | ||
| 716 | linkerr)) | ||
| 717 | ipath_dbg("Failed write to clear HT " | ||
| 718 | "linkerror%d\n", i); | ||
| 719 | if (pci_read_config_byte(dd->pcidev, link_off, | ||
| 720 | &linkerr)) | ||
| 721 | dev_info(&dd->pcidev->dev, | ||
| 722 | "Couldn't reread linkerror%d of " | ||
| 723 | "HT slave/primary block\n", i); | ||
| 724 | else if (linkerr & 0xf0) | ||
| 725 | dev_info(&dd->pcidev->dev, | ||
| 726 | "HT linkerror%d bits 0x%x " | ||
| 727 | "couldn't be cleared\n", | ||
| 728 | i, linkerr >> 4); | ||
| 729 | } | ||
| 730 | } | ||
| 731 | } | ||
| 732 | |||
| 733 | static int ipath_setup_ht_reset(struct ipath_devdata *dd) | ||
| 734 | { | ||
| 735 | ipath_dbg("No reset possible for HT-400\n"); | ||
| 736 | return 0; | ||
| 737 | } | ||
| 738 | |||
| 739 | #define HT_CAPABILITY_ID 0x08 /* HT capabilities not defined in kernel */ | ||
| 740 | #define HT_INTR_DISC_CONFIG 0x80 /* HT interrupt and discovery cap */ | ||
| 741 | #define HT_INTR_REG_INDEX 2 /* intconfig requires indirect accesses */ | ||
| 742 | |||
| 743 | /* | ||
| 744 | * Bits 13-15 of command==0 is slave/primary block. Clear any HT CRC | ||
| 745 | * errors. We only bother to do this at load time, because it's OK if | ||
| 746 | * it happened before we were loaded (first time after boot/reset), | ||
| 747 | * but any time after that, it's fatal anyway. Also need to not check | ||
| 748 | * for for upper byte errors if we are in 8 bit mode, so figure out | ||
| 749 | * our width. For now, at least, also complain if it's 8 bit. | ||
| 750 | */ | ||
| 751 | static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, | ||
| 752 | int pos, u8 cap_type) | ||
| 753 | { | ||
| 754 | u8 linkwidth = 0, linkerr, link_a_b_off, link_off; | ||
| 755 | u16 linkctrl = 0; | ||
| 756 | int i; | ||
| 757 | |||
| 758 | dd->ipath_ht_slave_off = pos; | ||
| 759 | /* command word, master_host bit */ | ||
| 760 | /* master host || slave */ | ||
| 761 | if ((cap_type >> 2) & 1) | ||
| 762 | link_a_b_off = 4; | ||
| 763 | else | ||
| 764 | link_a_b_off = 0; | ||
| 765 | ipath_cdbg(VERBOSE, "HT%u (Link %c) connected to processor\n", | ||
| 766 | link_a_b_off ? 1 : 0, | ||
| 767 | link_a_b_off ? 'B' : 'A'); | ||
| 768 | |||
| 769 | link_a_b_off += pos; | ||
| 770 | |||
| 771 | /* | ||
| 772 | * check both link control registers; clear both HT CRC sets if | ||
| 773 | * necessary. | ||
| 774 | */ | ||
| 775 | for (i = 0; i < 2; i++) { | ||
| 776 | link_off = pos + i * 4 + 0x4; | ||
| 777 | if (pci_read_config_word(pdev, link_off, &linkctrl)) | ||
| 778 | ipath_dev_err(dd, "Couldn't read HT link control%d " | ||
| 779 | "register\n", i); | ||
| 780 | else if (linkctrl & (0xf << 8)) { | ||
| 781 | ipath_cdbg(VERBOSE, "Clear linkctrl%d CRC Error " | ||
| 782 | "bits %x\n", i, linkctrl & (0xf << 8)); | ||
| 783 | /* | ||
| 784 | * now write them back to clear the error. | ||
| 785 | */ | ||
| 786 | pci_write_config_byte(pdev, link_off, | ||
| 787 | linkctrl & (0xf << 8)); | ||
| 788 | } | ||
| 789 | } | ||
| 790 | |||
| 791 | /* | ||
| 792 | * As with HT CRC bits, same for protocol errors that might occur | ||
| 793 | * during boot. | ||
| 794 | */ | ||
| 795 | for (i = 0; i < 2; i++) { | ||
| 796 | link_off = pos + i * 4 + 0xd; | ||
| 797 | if (pci_read_config_byte(pdev, link_off, &linkerr)) | ||
| 798 | dev_info(&pdev->dev, "Couldn't read linkerror%d " | ||
| 799 | "of HT slave/primary block\n", i); | ||
| 800 | else if (linkerr & 0xf0) { | ||
| 801 | ipath_cdbg(VERBOSE, "HT linkerr%d bits 0x%x set, " | ||
| 802 | "clearing\n", linkerr >> 4, i); | ||
| 803 | /* | ||
| 804 | * writing the linkerr bits that are set will clear | ||
| 805 | * them | ||
| 806 | */ | ||
| 807 | if (pci_write_config_byte | ||
| 808 | (pdev, link_off, linkerr)) | ||
| 809 | ipath_dbg("Failed write to clear HT " | ||
| 810 | "linkerror%d\n", i); | ||
| 811 | if (pci_read_config_byte(pdev, link_off, &linkerr)) | ||
| 812 | dev_info(&pdev->dev, "Couldn't reread " | ||
| 813 | "linkerror%d of HT slave/primary " | ||
| 814 | "block\n", i); | ||
| 815 | else if (linkerr & 0xf0) | ||
| 816 | dev_info(&pdev->dev, "HT linkerror%d bits " | ||
| 817 | "0x%x couldn't be cleared\n", | ||
| 818 | i, linkerr >> 4); | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | /* | ||
| 823 | * this is just for our link to the host, not devices connected | ||
| 824 | * through tunnel. | ||
| 825 | */ | ||
| 826 | |||
| 827 | if (pci_read_config_byte(pdev, link_a_b_off + 7, &linkwidth)) | ||
| 828 | ipath_dev_err(dd, "Couldn't read HT link width " | ||
| 829 | "config register\n"); | ||
| 830 | else { | ||
| 831 | u32 width; | ||
| 832 | switch (linkwidth & 7) { | ||
| 833 | case 5: | ||
| 834 | width = 4; | ||
| 835 | break; | ||
| 836 | case 4: | ||
| 837 | width = 2; | ||
| 838 | break; | ||
| 839 | case 3: | ||
| 840 | width = 32; | ||
| 841 | break; | ||
| 842 | case 1: | ||
| 843 | width = 16; | ||
| 844 | break; | ||
| 845 | case 0: | ||
| 846 | default: /* if wrong, assume 8 bit */ | ||
| 847 | width = 8; | ||
| 848 | break; | ||
| 849 | } | ||
| 850 | |||
| 851 | dd->ipath_htwidth = width; | ||
| 852 | |||
| 853 | if (linkwidth != 0x11) { | ||
| 854 | ipath_dev_err(dd, "Not configured for 16 bit HT " | ||
| 855 | "(%x)\n", linkwidth); | ||
| 856 | if (!(linkwidth & 0xf)) { | ||
| 857 | ipath_dbg("Will ignore HT lane1 errors\n"); | ||
| 858 | dd->ipath_flags |= IPATH_8BIT_IN_HT0; | ||
| 859 | } | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | /* | ||
| 864 | * this is just for our link to the host, not devices connected | ||
| 865 | * through tunnel. | ||
| 866 | */ | ||
| 867 | if (pci_read_config_byte(pdev, link_a_b_off + 0xd, &linkwidth)) | ||
| 868 | ipath_dev_err(dd, "Couldn't read HT link frequency " | ||
| 869 | "config register\n"); | ||
| 870 | else { | ||
| 871 | u32 speed; | ||
| 872 | switch (linkwidth & 0xf) { | ||
| 873 | case 6: | ||
| 874 | speed = 1000; | ||
| 875 | break; | ||
| 876 | case 5: | ||
| 877 | speed = 800; | ||
| 878 | break; | ||
| 879 | case 4: | ||
| 880 | speed = 600; | ||
| 881 | break; | ||
| 882 | case 3: | ||
| 883 | speed = 500; | ||
| 884 | break; | ||
| 885 | case 2: | ||
| 886 | speed = 400; | ||
| 887 | break; | ||
| 888 | case 1: | ||
| 889 | speed = 300; | ||
| 890 | break; | ||
| 891 | default: | ||
| 892 | /* | ||
| 893 | * assume reserved and vendor-specific are 200... | ||
| 894 | */ | ||
| 895 | case 0: | ||
| 896 | speed = 200; | ||
| 897 | break; | ||
| 898 | } | ||
| 899 | dd->ipath_htspeed = speed; | ||
| 900 | } | ||
| 901 | } | ||
| 902 | |||
| 903 | static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, | ||
| 904 | int pos) | ||
| 905 | { | ||
| 906 | u32 int_handler_addr_lower; | ||
| 907 | u32 int_handler_addr_upper; | ||
| 908 | u64 ihandler; | ||
| 909 | u32 intvec; | ||
| 910 | |||
| 911 | /* use indirection register to get the intr handler */ | ||
| 912 | pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10); | ||
| 913 | pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower); | ||
| 914 | pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11); | ||
| 915 | pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper); | ||
| 916 | |||
| 917 | ihandler = (u64) int_handler_addr_lower | | ||
| 918 | ((u64) int_handler_addr_upper << 32); | ||
| 919 | |||
| 920 | /* | ||
| 921 | * kernels with CONFIG_PCI_MSI set the vector in the irq field of | ||
| 922 | * struct pci_device, so we use that to program the HT-400 internal | ||
| 923 | * interrupt register (not config space) with that value. The BIOS | ||
| 924 | * must still have done the basic MSI setup. | ||
| 925 | */ | ||
| 926 | intvec = pdev->irq; | ||
| 927 | /* | ||
| 928 | * clear any vector bits there; normally not set but we'll overload | ||
| 929 | * this for some debug purposes (setting the HTC debug register | ||
| 930 | * value from software, rather than GPIOs), so it might be set on a | ||
| 931 | * driver reload. | ||
| 932 | */ | ||
| 933 | ihandler &= ~0xff0000; | ||
| 934 | /* x86 vector goes in intrinfo[23:16] */ | ||
| 935 | ihandler |= intvec << 16; | ||
| 936 | ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, " | ||
| 937 | "interruptconfig %llx\n", int_handler_addr_lower, | ||
| 938 | int_handler_addr_upper, intvec, | ||
| 939 | (unsigned long long) ihandler); | ||
| 940 | |||
| 941 | /* can't program yet, so save for interrupt setup */ | ||
| 942 | dd->ipath_intconfig = ihandler; | ||
| 943 | /* keep going, so we find link control stuff also */ | ||
| 944 | |||
| 945 | return ihandler != 0; | ||
| 946 | } | ||
| 947 | |||
| 948 | /** | ||
| 949 | * ipath_setup_ht_config - setup the interruptconfig register | ||
| 950 | * @dd: the infinipath device | ||
| 951 | * @pdev: the PCI device | ||
| 952 | * | ||
| 953 | * setup the interruptconfig register from the HT config info. | ||
| 954 | * Also clear CRC errors in HT linkcontrol, if necessary. | ||
| 955 | * This is done only for the real hardware. It is done before | ||
| 956 | * chip address space is initted, so can't touch infinipath registers | ||
| 957 | */ | ||
| 958 | static int ipath_setup_ht_config(struct ipath_devdata *dd, | ||
| 959 | struct pci_dev *pdev) | ||
| 960 | { | ||
| 961 | int pos, ret = 0; | ||
| 962 | int ihandler = 0; | ||
| 963 | |||
| 964 | /* | ||
| 965 | * Read the capability info to find the interrupt info, and also | ||
| 966 | * handle clearing CRC errors in linkctrl register if necessary. We | ||
| 967 | * do this early, before we ever enable errors or hardware errors, | ||
| 968 | * mostly to avoid causing the chip to enter freeze mode. | ||
| 969 | */ | ||
| 970 | pos = pci_find_capability(pdev, HT_CAPABILITY_ID); | ||
| 971 | if (!pos) { | ||
| 972 | ipath_dev_err(dd, "Couldn't find HyperTransport " | ||
| 973 | "capability; no interrupts\n"); | ||
| 974 | ret = -ENODEV; | ||
| 975 | goto bail; | ||
| 976 | } | ||
| 977 | do { | ||
| 978 | u8 cap_type; | ||
| 979 | |||
| 980 | /* the HT capability type byte is 3 bytes after the | ||
| 981 | * capability byte. | ||
| 982 | */ | ||
| 983 | if (pci_read_config_byte(pdev, pos + 3, &cap_type)) { | ||
| 984 | dev_info(&pdev->dev, "Couldn't read config " | ||
| 985 | "command @ %d\n", pos); | ||
| 986 | continue; | ||
| 987 | } | ||
| 988 | if (!(cap_type & 0xE0)) | ||
| 989 | slave_or_pri_blk(dd, pdev, pos, cap_type); | ||
| 990 | else if (cap_type == HT_INTR_DISC_CONFIG) | ||
| 991 | ihandler = set_int_handler(dd, pdev, pos); | ||
| 992 | } while ((pos = pci_find_next_capability(pdev, pos, | ||
| 993 | HT_CAPABILITY_ID))); | ||
| 994 | |||
| 995 | if (!ihandler) { | ||
| 996 | ipath_dev_err(dd, "Couldn't find interrupt handler in " | ||
| 997 | "config space\n"); | ||
| 998 | ret = -ENODEV; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | bail: | ||
| 1002 | return ret; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | /** | ||
| 1006 | * ipath_setup_ht_cleanup - clean up any per-chip chip-specific stuff | ||
| 1007 | * @dd: the infinipath device | ||
| 1008 | * | ||
| 1009 | * Called during driver unload. | ||
| 1010 | * This is currently a nop for the HT-400, not for all chips | ||
| 1011 | */ | ||
| 1012 | static void ipath_setup_ht_cleanup(struct ipath_devdata *dd) | ||
| 1013 | { | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | /** | ||
| 1017 | * ipath_setup_ht_setextled - set the state of the two external LEDs | ||
| 1018 | * @dd: the infinipath device | ||
| 1019 | * @lst: the L state | ||
| 1020 | * @ltst: the LT state | ||
| 1021 | * | ||
| 1022 | * Set the state of the two external LEDs, to indicate physical and | ||
| 1023 | * logical state of IB link. For this chip (at least with recommended | ||
| 1024 | * board pinouts), LED1 is Green (physical state), and LED2 is Yellow | ||
| 1025 | * (logical state) | ||
| 1026 | * | ||
| 1027 | * Note: We try to match the Mellanox HCA LED behavior as best | ||
| 1028 | * we can. Green indicates physical link state is OK (something is | ||
| 1029 | * plugged in, and we can train). | ||
| 1030 | * Amber indicates the link is logically up (ACTIVE). | ||
| 1031 | * Mellanox further blinks the amber LED to indicate data packet | ||
| 1032 | * activity, but we have no hardware support for that, so it would | ||
| 1033 | * require waking up every 10-20 msecs and checking the counters | ||
| 1034 | * on the chip, and then turning the LED off if appropriate. That's | ||
| 1035 | * visible overhead, so not something we will do. | ||
| 1036 | * | ||
| 1037 | */ | ||
| 1038 | static void ipath_setup_ht_setextled(struct ipath_devdata *dd, | ||
| 1039 | u64 lst, u64 ltst) | ||
| 1040 | { | ||
| 1041 | u64 extctl; | ||
| 1042 | |||
| 1043 | /* the diags use the LED to indicate diag info, so we leave | ||
| 1044 | * the external LED alone when the diags are running */ | ||
| 1045 | if (ipath_diag_inuse) | ||
| 1046 | return; | ||
| 1047 | |||
| 1048 | /* | ||
| 1049 | * start by setting both LED control bits to off, then turn | ||
| 1050 | * on the appropriate bit(s). | ||
| 1051 | */ | ||
| 1052 | if (dd->ipath_boardrev == 8) { /* LS/X-1 uses different pins */ | ||
| 1053 | /* | ||
| 1054 | * major difference is that INFINIPATH_EXTC_LEDGBLERR_OFF | ||
| 1055 | * is inverted, because it is normally used to indicate | ||
| 1056 | * a hardware fault at reset, if there were errors | ||
| 1057 | */ | ||
| 1058 | extctl = (dd->ipath_extctrl & ~INFINIPATH_EXTC_LEDGBLOK_ON) | ||
| 1059 | | INFINIPATH_EXTC_LEDGBLERR_OFF; | ||
| 1060 | if (ltst == INFINIPATH_IBCS_LT_STATE_LINKUP) | ||
| 1061 | extctl &= ~INFINIPATH_EXTC_LEDGBLERR_OFF; | ||
| 1062 | if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE) | ||
| 1063 | extctl |= INFINIPATH_EXTC_LEDGBLOK_ON; | ||
| 1064 | } | ||
| 1065 | else { | ||
| 1066 | extctl = dd->ipath_extctrl & | ||
| 1067 | ~(INFINIPATH_EXTC_LED1PRIPORT_ON | | ||
| 1068 | INFINIPATH_EXTC_LED2PRIPORT_ON); | ||
| 1069 | if (ltst == INFINIPATH_IBCS_LT_STATE_LINKUP) | ||
| 1070 | extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON; | ||
| 1071 | if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE) | ||
| 1072 | extctl |= INFINIPATH_EXTC_LED2PRIPORT_ON; | ||
| 1073 | } | ||
| 1074 | dd->ipath_extctrl = extctl; | ||
| 1075 | ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static void ipath_init_ht_variables(void) | ||
| 1079 | { | ||
| 1080 | ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; | ||
| 1081 | ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; | ||
| 1082 | ipath_gpio_sda = IPATH_GPIO_SDA; | ||
| 1083 | ipath_gpio_scl = IPATH_GPIO_SCL; | ||
| 1084 | |||
| 1085 | infinipath_i_bitsextant = | ||
| 1086 | (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | | ||
| 1087 | (INFINIPATH_I_RCVAVAIL_MASK << | ||
| 1088 | INFINIPATH_I_RCVAVAIL_SHIFT) | | ||
| 1089 | INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT | | ||
| 1090 | INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO; | ||
| 1091 | |||
| 1092 | infinipath_e_bitsextant = | ||
| 1093 | INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC | | ||
| 1094 | INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN | | ||
| 1095 | INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN | | ||
| 1096 | INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RUNEXPCHAR | | ||
| 1097 | INFINIPATH_E_RUNSUPVL | INFINIPATH_E_REBP | | ||
| 1098 | INFINIPATH_E_RIBFLOW | INFINIPATH_E_RBADVERSION | | ||
| 1099 | INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | | ||
| 1100 | INFINIPATH_E_RBADTID | INFINIPATH_E_RHDRLEN | | ||
| 1101 | INFINIPATH_E_RHDR | INFINIPATH_E_RIBLOSTLINK | | ||
| 1102 | INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SMAXPKTLEN | | ||
| 1103 | INFINIPATH_E_SUNDERRUN | INFINIPATH_E_SPKTLEN | | ||
| 1104 | INFINIPATH_E_SDROPPEDSMPPKT | INFINIPATH_E_SDROPPEDDATAPKT | | ||
| 1105 | INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | | ||
| 1106 | INFINIPATH_E_SUNSUPVL | INFINIPATH_E_IBSTATUSCHANGED | | ||
| 1107 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET | | ||
| 1108 | INFINIPATH_E_HARDWARE; | ||
| 1109 | |||
| 1110 | infinipath_hwe_bitsextant = | ||
| 1111 | (INFINIPATH_HWE_HTCMEMPARITYERR_MASK << | ||
| 1112 | INFINIPATH_HWE_HTCMEMPARITYERR_SHIFT) | | ||
| 1113 | (INFINIPATH_HWE_TXEMEMPARITYERR_MASK << | ||
| 1114 | INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | | ||
| 1115 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | ||
| 1116 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | | ||
| 1117 | INFINIPATH_HWE_HTCLNKABYTE0CRCERR | | ||
| 1118 | INFINIPATH_HWE_HTCLNKABYTE1CRCERR | | ||
| 1119 | INFINIPATH_HWE_HTCLNKBBYTE0CRCERR | | ||
| 1120 | INFINIPATH_HWE_HTCLNKBBYTE1CRCERR | | ||
| 1121 | INFINIPATH_HWE_HTCMISCERR4 | | ||
| 1122 | INFINIPATH_HWE_HTCMISCERR5 | INFINIPATH_HWE_HTCMISCERR6 | | ||
| 1123 | INFINIPATH_HWE_HTCMISCERR7 | | ||
| 1124 | INFINIPATH_HWE_HTCBUSTREQPARITYERR | | ||
| 1125 | INFINIPATH_HWE_HTCBUSTRESPPARITYERR | | ||
| 1126 | INFINIPATH_HWE_HTCBUSIREQPARITYERR | | ||
| 1127 | INFINIPATH_HWE_RXDSYNCMEMPARITYERR | | ||
| 1128 | INFINIPATH_HWE_MEMBISTFAILED | | ||
| 1129 | INFINIPATH_HWE_COREPLL_FBSLIP | | ||
| 1130 | INFINIPATH_HWE_COREPLL_RFSLIP | | ||
| 1131 | INFINIPATH_HWE_HTBPLL_FBSLIP | | ||
| 1132 | INFINIPATH_HWE_HTBPLL_RFSLIP | | ||
| 1133 | INFINIPATH_HWE_HTAPLL_FBSLIP | | ||
| 1134 | INFINIPATH_HWE_HTAPLL_RFSLIP | | ||
| 1135 | INFINIPATH_HWE_SERDESPLLFAILED | | ||
| 1136 | INFINIPATH_HWE_IBCBUSTOSPCPARITYERR | | ||
| 1137 | INFINIPATH_HWE_IBCBUSFRSPCPARITYERR; | ||
| 1138 | |||
| 1139 | infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | ||
| 1140 | infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | /** | ||
| 1144 | * ipath_ht_init_hwerrors - enable hardware errors | ||
| 1145 | * @dd: the infinipath device | ||
| 1146 | * | ||
| 1147 | * now that we have finished initializing everything that might reasonably | ||
| 1148 | * cause a hardware error, and cleared those errors bits as they occur, | ||
| 1149 | * we can enable hardware errors in the mask (potentially enabling | ||
| 1150 | * freeze mode), and enable hardware errors as errors (along with | ||
| 1151 | * everything else) in errormask | ||
| 1152 | */ | ||
| 1153 | static void ipath_ht_init_hwerrors(struct ipath_devdata *dd) | ||
| 1154 | { | ||
| 1155 | ipath_err_t val; | ||
| 1156 | u64 extsval; | ||
| 1157 | |||
| 1158 | extsval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); | ||
| 1159 | |||
| 1160 | if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST)) | ||
| 1161 | ipath_dev_err(dd, "MemBIST did not complete!\n"); | ||
| 1162 | |||
| 1163 | ipath_check_htlink(dd); | ||
| 1164 | |||
| 1165 | /* barring bugs, all hwerrors become interrupts, which can */ | ||
| 1166 | val = -1LL; | ||
| 1167 | /* don't look at crc lane1 if 8 bit */ | ||
| 1168 | if (dd->ipath_flags & IPATH_8BIT_IN_HT0) | ||
| 1169 | val &= ~infinipath_hwe_htclnkabyte1crcerr; | ||
| 1170 | /* don't look at crc lane1 if 8 bit */ | ||
| 1171 | if (dd->ipath_flags & IPATH_8BIT_IN_HT1) | ||
| 1172 | val &= ~infinipath_hwe_htclnkbbyte1crcerr; | ||
| 1173 | |||
| 1174 | /* | ||
| 1175 | * disable RXDSYNCMEMPARITY because external serdes is unused, | ||
| 1176 | * and therefore the logic will never be used or initialized, | ||
| 1177 | * and uninitialized state will normally result in this error | ||
| 1178 | * being asserted. Similarly for the external serdess pll | ||
| 1179 | * lock signal. | ||
| 1180 | */ | ||
| 1181 | val &= ~(INFINIPATH_HWE_SERDESPLLFAILED | | ||
| 1182 | INFINIPATH_HWE_RXDSYNCMEMPARITYERR); | ||
| 1183 | |||
| 1184 | /* | ||
| 1185 | * Disable MISCERR4 because of an inversion in the HT core | ||
| 1186 | * logic checking for errors that cause this bit to be set. | ||
| 1187 | * The errata can also cause the protocol error bit to be set | ||
| 1188 | * in the HT config space linkerror register(s). | ||
| 1189 | */ | ||
| 1190 | val &= ~INFINIPATH_HWE_HTCMISCERR4; | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * PLL ignored because MDIO interface has a logic problem | ||
| 1194 | * for reads, on Comstock and Ponderosa. BRINGUP | ||
| 1195 | */ | ||
| 1196 | if (dd->ipath_boardrev == 4 || dd->ipath_boardrev == 9) | ||
| 1197 | val &= ~INFINIPATH_HWE_SERDESPLLFAILED; | ||
| 1198 | dd->ipath_hwerrmask = val; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | /** | ||
| 1202 | * ipath_ht_bringup_serdes - bring up the serdes | ||
| 1203 | * @dd: the infinipath device | ||
| 1204 | */ | ||
| 1205 | static int ipath_ht_bringup_serdes(struct ipath_devdata *dd) | ||
| 1206 | { | ||
| 1207 | u64 val, config1; | ||
| 1208 | int ret = 0, change = 0; | ||
| 1209 | |||
| 1210 | ipath_dbg("Trying to bringup serdes\n"); | ||
| 1211 | |||
| 1212 | if (ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus) & | ||
| 1213 | INFINIPATH_HWE_SERDESPLLFAILED) | ||
| 1214 | { | ||
| 1215 | ipath_dbg("At start, serdes PLL failed bit set in " | ||
| 1216 | "hwerrstatus, clearing and continuing\n"); | ||
| 1217 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 1218 | INFINIPATH_HWE_SERDESPLLFAILED); | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 1222 | config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1); | ||
| 1223 | |||
| 1224 | ipath_cdbg(VERBOSE, "Initial serdes status is config0=%llx " | ||
| 1225 | "config1=%llx, sstatus=%llx xgxs %llx\n", | ||
| 1226 | (unsigned long long) val, (unsigned long long) config1, | ||
| 1227 | (unsigned long long) | ||
| 1228 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesstatus), | ||
| 1229 | (unsigned long long) | ||
| 1230 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | ||
| 1231 | |||
| 1232 | /* force reset on */ | ||
| 1233 | val |= INFINIPATH_SERDC0_RESET_PLL | ||
| 1234 | /* | INFINIPATH_SERDC0_RESET_MASK */ | ||
| 1235 | ; | ||
| 1236 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 1237 | udelay(15); /* need pll reset set at least for a bit */ | ||
| 1238 | |||
| 1239 | if (val & INFINIPATH_SERDC0_RESET_PLL) { | ||
| 1240 | u64 val2 = val &= ~INFINIPATH_SERDC0_RESET_PLL; | ||
| 1241 | /* set lane resets, and tx idle, during pll reset */ | ||
| 1242 | val2 |= INFINIPATH_SERDC0_RESET_MASK | | ||
| 1243 | INFINIPATH_SERDC0_TXIDLE; | ||
| 1244 | ipath_cdbg(VERBOSE, "Clearing serdes PLL reset (writing " | ||
| 1245 | "%llx)\n", (unsigned long long) val2); | ||
| 1246 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, | ||
| 1247 | val2); | ||
| 1248 | /* | ||
| 1249 | * be sure chip saw it | ||
| 1250 | */ | ||
| 1251 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 1252 | /* | ||
| 1253 | * need pll reset clear at least 11 usec before lane | ||
| 1254 | * resets cleared; give it a few more | ||
| 1255 | */ | ||
| 1256 | udelay(15); | ||
| 1257 | val = val2; /* for check below */ | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | if (val & (INFINIPATH_SERDC0_RESET_PLL | | ||
| 1261 | INFINIPATH_SERDC0_RESET_MASK | | ||
| 1262 | INFINIPATH_SERDC0_TXIDLE)) { | ||
| 1263 | val &= ~(INFINIPATH_SERDC0_RESET_PLL | | ||
| 1264 | INFINIPATH_SERDC0_RESET_MASK | | ||
| 1265 | INFINIPATH_SERDC0_TXIDLE); | ||
| 1266 | /* clear them */ | ||
| 1267 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, | ||
| 1268 | val); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | ||
| 1272 | if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) & | ||
| 1273 | INFINIPATH_XGXS_MDIOADDR_MASK) != 3) { | ||
| 1274 | val &= ~(INFINIPATH_XGXS_MDIOADDR_MASK << | ||
| 1275 | INFINIPATH_XGXS_MDIOADDR_SHIFT); | ||
| 1276 | /* | ||
| 1277 | * we use address 3 | ||
| 1278 | */ | ||
| 1279 | val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT; | ||
| 1280 | change = 1; | ||
| 1281 | } | ||
| 1282 | if (val & INFINIPATH_XGXS_RESET) { | ||
| 1283 | /* normally true after boot */ | ||
| 1284 | val &= ~INFINIPATH_XGXS_RESET; | ||
| 1285 | change = 1; | ||
| 1286 | } | ||
| 1287 | if (change) | ||
| 1288 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); | ||
| 1289 | |||
| 1290 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 1291 | |||
| 1292 | /* clear current and de-emphasis bits */ | ||
| 1293 | config1 &= ~0x0ffffffff00ULL; | ||
| 1294 | /* set current to 20ma */ | ||
| 1295 | config1 |= 0x00000000000ULL; | ||
| 1296 | /* set de-emphasis to -5.68dB */ | ||
| 1297 | config1 |= 0x0cccc000000ULL; | ||
| 1298 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig1, config1); | ||
| 1299 | |||
| 1300 | ipath_cdbg(VERBOSE, "After setup: serdes status is config0=%llx " | ||
| 1301 | "config1=%llx, sstatus=%llx xgxs %llx\n", | ||
| 1302 | (unsigned long long) val, (unsigned long long) config1, | ||
| 1303 | (unsigned long long) | ||
| 1304 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesstatus), | ||
| 1305 | (unsigned long long) | ||
| 1306 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | ||
| 1307 | |||
| 1308 | if (!ipath_waitfor_mdio_cmdready(dd)) { | ||
| 1309 | ipath_write_kreg(dd, dd->ipath_kregs->kr_mdio, | ||
| 1310 | ipath_mdio_req(IPATH_MDIO_CMD_READ, 31, | ||
| 1311 | IPATH_MDIO_CTRL_XGXS_REG_8, | ||
| 1312 | 0)); | ||
| 1313 | if (ipath_waitfor_complete(dd, dd->ipath_kregs->kr_mdio, | ||
| 1314 | IPATH_MDIO_DATAVALID, &val)) | ||
| 1315 | ipath_dbg("Never got MDIO data for XGXS status " | ||
| 1316 | "read\n"); | ||
| 1317 | else | ||
| 1318 | ipath_cdbg(VERBOSE, "MDIO Read reg8, " | ||
| 1319 | "'bank' 31 %x\n", (u32) val); | ||
| 1320 | } else | ||
| 1321 | ipath_dbg("Never got MDIO cmdready for XGXS status read\n"); | ||
| 1322 | |||
| 1323 | return ret; /* for now, say we always succeeded */ | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | /** | ||
| 1327 | * ipath_ht_quiet_serdes - set serdes to txidle | ||
| 1328 | * @dd: the infinipath device | ||
| 1329 | * driver is being unloaded | ||
| 1330 | */ | ||
| 1331 | static void ipath_ht_quiet_serdes(struct ipath_devdata *dd) | ||
| 1332 | { | ||
| 1333 | u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 1334 | |||
| 1335 | val |= INFINIPATH_SERDC0_TXIDLE; | ||
| 1336 | ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n", | ||
| 1337 | (unsigned long long) val); | ||
| 1338 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | static int ipath_ht_intconfig(struct ipath_devdata *dd) | ||
| 1342 | { | ||
| 1343 | int ret; | ||
| 1344 | |||
| 1345 | if (!dd->ipath_intconfig) { | ||
| 1346 | ipath_dev_err(dd, "No interrupts enabled, couldn't setup " | ||
| 1347 | "interrupt address\n"); | ||
| 1348 | ret = 1; | ||
| 1349 | goto bail; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, | ||
| 1353 | dd->ipath_intconfig); /* interrupt address */ | ||
| 1354 | ret = 0; | ||
| 1355 | |||
| 1356 | bail: | ||
| 1357 | return ret; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /** | ||
| 1361 | * ipath_pe_put_tid - write a TID in chip | ||
| 1362 | * @dd: the infinipath device | ||
| 1363 | * @tidptr: pointer to the expected TID (in chip) to udpate | ||
| 1364 | * @tidtype: 0 for eager, 1 for expected | ||
| 1365 | * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing | ||
| 1366 | * | ||
| 1367 | * This exists as a separate routine to allow for special locking etc. | ||
| 1368 | * It's used for both the full cleanup on exit, as well as the normal | ||
| 1369 | * setup and teardown. | ||
| 1370 | */ | ||
| 1371 | static void ipath_ht_put_tid(struct ipath_devdata *dd, | ||
| 1372 | u64 __iomem *tidptr, u32 type, | ||
| 1373 | unsigned long pa) | ||
| 1374 | { | ||
| 1375 | if (pa != dd->ipath_tidinvalid) { | ||
| 1376 | if (unlikely((pa & ~INFINIPATH_RT_ADDR_MASK))) { | ||
| 1377 | dev_info(&dd->pcidev->dev, | ||
| 1378 | "physaddr %lx has more than " | ||
| 1379 | "40 bits, using only 40!!!\n", pa); | ||
| 1380 | pa &= INFINIPATH_RT_ADDR_MASK; | ||
| 1381 | } | ||
| 1382 | if (type == 0) | ||
| 1383 | pa |= dd->ipath_tidtemplate; | ||
| 1384 | else { | ||
| 1385 | /* in words (fixed, full page). */ | ||
| 1386 | u64 lenvalid = PAGE_SIZE >> 2; | ||
| 1387 | lenvalid <<= INFINIPATH_RT_BUFSIZE_SHIFT; | ||
| 1388 | pa |= lenvalid | INFINIPATH_RT_VALID; | ||
| 1389 | } | ||
| 1390 | } | ||
| 1391 | if (dd->ipath_kregbase) | ||
| 1392 | writeq(pa, tidptr); | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | /** | ||
| 1396 | * ipath_ht_clear_tid - clear all TID entries for a port, expected and eager | ||
| 1397 | * @dd: the infinipath device | ||
| 1398 | * @port: the port | ||
| 1399 | * | ||
| 1400 | * Used from ipath_close(), and at chip initialization. | ||
| 1401 | */ | ||
| 1402 | static void ipath_ht_clear_tids(struct ipath_devdata *dd, unsigned port) | ||
| 1403 | { | ||
| 1404 | u64 __iomem *tidbase; | ||
| 1405 | int i; | ||
| 1406 | |||
| 1407 | if (!dd->ipath_kregbase) | ||
| 1408 | return; | ||
| 1409 | |||
| 1410 | ipath_cdbg(VERBOSE, "Invalidate TIDs for port %u\n", port); | ||
| 1411 | |||
| 1412 | /* | ||
| 1413 | * need to invalidate all of the expected TID entries for this | ||
| 1414 | * port, so we don't have valid entries that might somehow get | ||
| 1415 | * used (early in next use of this port, or through some bug) | ||
| 1416 | */ | ||
| 1417 | tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) + | ||
| 1418 | dd->ipath_rcvtidbase + | ||
| 1419 | port * dd->ipath_rcvtidcnt * | ||
| 1420 | sizeof(*tidbase)); | ||
| 1421 | for (i = 0; i < dd->ipath_rcvtidcnt; i++) | ||
| 1422 | ipath_ht_put_tid(dd, &tidbase[i], 1, dd->ipath_tidinvalid); | ||
| 1423 | |||
| 1424 | tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) + | ||
| 1425 | dd->ipath_rcvegrbase + | ||
| 1426 | port * dd->ipath_rcvegrcnt * | ||
| 1427 | sizeof(*tidbase)); | ||
| 1428 | |||
| 1429 | for (i = 0; i < dd->ipath_rcvegrcnt; i++) | ||
| 1430 | ipath_ht_put_tid(dd, &tidbase[i], 0, dd->ipath_tidinvalid); | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | /** | ||
| 1434 | * ipath_ht_tidtemplate - setup constants for TID updates | ||
| 1435 | * @dd: the infinipath device | ||
| 1436 | * | ||
| 1437 | * We setup stuff that we use a lot, to avoid calculating each time | ||
| 1438 | */ | ||
| 1439 | static void ipath_ht_tidtemplate(struct ipath_devdata *dd) | ||
| 1440 | { | ||
| 1441 | dd->ipath_tidtemplate = dd->ipath_ibmaxlen >> 2; | ||
| 1442 | dd->ipath_tidtemplate <<= INFINIPATH_RT_BUFSIZE_SHIFT; | ||
| 1443 | dd->ipath_tidtemplate |= INFINIPATH_RT_VALID; | ||
| 1444 | |||
| 1445 | /* | ||
| 1446 | * work around chip errata bug 7358, by marking invalid tids | ||
| 1447 | * as having max length | ||
| 1448 | */ | ||
| 1449 | dd->ipath_tidinvalid = (-1LL & INFINIPATH_RT_BUFSIZE_MASK) << | ||
| 1450 | INFINIPATH_RT_BUFSIZE_SHIFT; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static int ipath_ht_early_init(struct ipath_devdata *dd) | ||
| 1454 | { | ||
| 1455 | u32 __iomem *piobuf; | ||
| 1456 | u32 pioincr, val32, egrsize; | ||
| 1457 | int i; | ||
| 1458 | |||
| 1459 | /* | ||
| 1460 | * one cache line; long IB headers will spill over into received | ||
| 1461 | * buffer | ||
| 1462 | */ | ||
| 1463 | dd->ipath_rcvhdrentsize = 16; | ||
| 1464 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; | ||
| 1465 | |||
| 1466 | /* | ||
| 1467 | * For HT-400, we allocate a somewhat overly large eager buffer, | ||
| 1468 | * such that we can guarantee that we can receive the largest | ||
| 1469 | * packet that we can send out. To truly support a 4KB MTU, | ||
| 1470 | * we need to bump this to a large value. To date, other than | ||
| 1471 | * testing, we have never encountered an HCA that can really | ||
| 1472 | * send 4KB MTU packets, so we do not handle that (we'll get | ||
| 1473 | * errors interrupts if we ever see one). | ||
| 1474 | */ | ||
| 1475 | dd->ipath_rcvegrbufsize = dd->ipath_piosize2k; | ||
| 1476 | egrsize = dd->ipath_rcvegrbufsize; | ||
| 1477 | |||
| 1478 | /* | ||
| 1479 | * the min() check here is currently a nop, but it may not | ||
| 1480 | * always be, depending on just how we do ipath_rcvegrbufsize | ||
| 1481 | */ | ||
| 1482 | dd->ipath_ibmaxlen = min(dd->ipath_piosize2k, | ||
| 1483 | dd->ipath_rcvegrbufsize); | ||
| 1484 | dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen; | ||
| 1485 | ipath_ht_tidtemplate(dd); | ||
| 1486 | |||
| 1487 | /* | ||
| 1488 | * zero all the TID entries at startup. We do this for sanity, | ||
| 1489 | * in case of a previous driver crash of some kind, and also | ||
| 1490 | * because the chip powers up with these memories in an unknown | ||
| 1491 | * state. Use portcnt, not cfgports, since this is for the | ||
| 1492 | * full chip, not for current (possibly different) configuration | ||
| 1493 | * value. | ||
| 1494 | * Chip Errata bug 6447 | ||
| 1495 | */ | ||
| 1496 | for (val32 = 0; val32 < dd->ipath_portcnt; val32++) | ||
| 1497 | ipath_ht_clear_tids(dd, val32); | ||
| 1498 | |||
| 1499 | /* | ||
| 1500 | * write the pbc of each buffer, to be sure it's initialized, then | ||
| 1501 | * cancel all the buffers, and also abort any packets that might | ||
| 1502 | * have been in flight for some reason (the latter is for driver | ||
| 1503 | * unload/reload, but isn't a bad idea at first init). PIO send | ||
| 1504 | * isn't enabled at this point, so there is no danger of sending | ||
| 1505 | * these out on the wire. | ||
| 1506 | * Chip Errata bug 6610 | ||
| 1507 | */ | ||
| 1508 | piobuf = (u32 __iomem *) (((char __iomem *)(dd->ipath_kregbase)) + | ||
| 1509 | dd->ipath_piobufbase); | ||
| 1510 | pioincr = dd->ipath_palign / sizeof(*piobuf); | ||
| 1511 | for (i = 0; i < dd->ipath_piobcnt2k; i++) { | ||
| 1512 | /* | ||
| 1513 | * reasonable word count, just to init pbc | ||
| 1514 | */ | ||
| 1515 | writel(16, piobuf); | ||
| 1516 | piobuf += pioincr; | ||
| 1517 | } | ||
| 1518 | /* | ||
| 1519 | * self-clearing | ||
| 1520 | */ | ||
| 1521 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 1522 | INFINIPATH_S_ABORT); | ||
| 1523 | return 0; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | /** | ||
| 1527 | * ipath_init_ht_get_base_info - set chip-specific flags for user code | ||
| 1528 | * @dd: the infinipath device | ||
| 1529 | * @kbase: ipath_base_info pointer | ||
| 1530 | * | ||
| 1531 | * We set the PCIE flag because the lower bandwidth on PCIe vs | ||
| 1532 | * HyperTransport can affect some user packet algorithims. | ||
| 1533 | */ | ||
| 1534 | static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase) | ||
| 1535 | { | ||
| 1536 | struct ipath_base_info *kinfo = kbase; | ||
| 1537 | |||
| 1538 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_HT | | ||
| 1539 | IPATH_RUNTIME_RCVHDR_COPY; | ||
| 1540 | |||
| 1541 | return 0; | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | /** | ||
| 1545 | * ipath_init_ht400_funcs - set up the chip-specific function pointers | ||
| 1546 | * @dd: the infinipath device | ||
| 1547 | * | ||
| 1548 | * This is global, and is called directly at init to set up the | ||
| 1549 | * chip-specific function pointers for later use. | ||
| 1550 | */ | ||
| 1551 | void ipath_init_ht400_funcs(struct ipath_devdata *dd) | ||
| 1552 | { | ||
| 1553 | dd->ipath_f_intrsetup = ipath_ht_intconfig; | ||
| 1554 | dd->ipath_f_bus = ipath_setup_ht_config; | ||
| 1555 | dd->ipath_f_reset = ipath_setup_ht_reset; | ||
| 1556 | dd->ipath_f_get_boardname = ipath_ht_boardname; | ||
| 1557 | dd->ipath_f_init_hwerrors = ipath_ht_init_hwerrors; | ||
| 1558 | dd->ipath_f_init_hwerrors = ipath_ht_init_hwerrors; | ||
| 1559 | dd->ipath_f_early_init = ipath_ht_early_init; | ||
| 1560 | dd->ipath_f_handle_hwerrors = ipath_ht_handle_hwerrors; | ||
| 1561 | dd->ipath_f_quiet_serdes = ipath_ht_quiet_serdes; | ||
| 1562 | dd->ipath_f_bringup_serdes = ipath_ht_bringup_serdes; | ||
| 1563 | dd->ipath_f_clear_tids = ipath_ht_clear_tids; | ||
| 1564 | dd->ipath_f_put_tid = ipath_ht_put_tid; | ||
| 1565 | dd->ipath_f_cleanup = ipath_setup_ht_cleanup; | ||
| 1566 | dd->ipath_f_setextled = ipath_setup_ht_setextled; | ||
| 1567 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; | ||
| 1568 | |||
| 1569 | /* | ||
| 1570 | * initialize chip-specific variables | ||
| 1571 | */ | ||
| 1572 | dd->ipath_f_tidtemplate = ipath_ht_tidtemplate; | ||
| 1573 | |||
| 1574 | /* | ||
| 1575 | * setup the register offsets, since they are different for each | ||
| 1576 | * chip | ||
| 1577 | */ | ||
| 1578 | dd->ipath_kregs = &ipath_ht_kregs; | ||
| 1579 | dd->ipath_cregs = &ipath_ht_cregs; | ||
| 1580 | |||
| 1581 | /* | ||
| 1582 | * do very early init that is needed before ipath_f_bus is | ||
| 1583 | * called | ||
| 1584 | */ | ||
| 1585 | ipath_init_ht_variables(); | ||
| 1586 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c new file mode 100644 index 000000000000..2823ff9c0c62 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
| @@ -0,0 +1,951 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/pci.h> | ||
| 34 | #include <linux/netdevice.h> | ||
| 35 | #include <linux/vmalloc.h> | ||
| 36 | |||
| 37 | #include "ipath_kernel.h" | ||
| 38 | #include "ips_common.h" | ||
| 39 | |||
| 40 | /* | ||
| 41 | * min buffers we want to have per port, after driver | ||
| 42 | */ | ||
| 43 | #define IPATH_MIN_USER_PORT_BUFCNT 8 | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Number of ports we are configured to use (to allow for more pio | ||
| 47 | * buffers per port, etc.) Zero means use chip value. | ||
| 48 | */ | ||
| 49 | static ushort ipath_cfgports; | ||
| 50 | |||
| 51 | module_param_named(cfgports, ipath_cfgports, ushort, S_IRUGO); | ||
| 52 | MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Number of buffers reserved for driver (layered drivers and SMA | ||
| 56 | * send). Reserved at end of buffer list. | ||
| 57 | */ | ||
| 58 | static ushort ipath_kpiobufs = 32; | ||
| 59 | |||
| 60 | static int ipath_set_kpiobufs(const char *val, struct kernel_param *kp); | ||
| 61 | |||
| 62 | module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_uint, | ||
| 63 | &ipath_kpiobufs, S_IWUSR | S_IRUGO); | ||
| 64 | MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver"); | ||
| 65 | |||
| 66 | /** | ||
| 67 | * create_port0_egr - allocate the eager TID buffers | ||
| 68 | * @dd: the infinipath device | ||
| 69 | * | ||
| 70 | * This code is now quite different for user and kernel, because | ||
| 71 | * the kernel uses skb's, for the accelerated network performance. | ||
| 72 | * This is the kernel (port0) version. | ||
| 73 | * | ||
| 74 | * Allocate the eager TID buffers and program them into infinipath. | ||
| 75 | * We use the network layer alloc_skb() allocator to allocate the | ||
| 76 | * memory, and either use the buffers as is for things like SMA | ||
| 77 | * packets, or pass the buffers up to the ipath layered driver and | ||
| 78 | * thence the network layer, replacing them as we do so (see | ||
| 79 | * ipath_rcv_layer()). | ||
| 80 | */ | ||
| 81 | static int create_port0_egr(struct ipath_devdata *dd) | ||
| 82 | { | ||
| 83 | unsigned e, egrcnt; | ||
| 84 | struct sk_buff **skbs; | ||
| 85 | int ret; | ||
| 86 | |||
| 87 | egrcnt = dd->ipath_rcvegrcnt; | ||
| 88 | |||
| 89 | skbs = vmalloc(sizeof(*dd->ipath_port0_skbs) * egrcnt); | ||
| 90 | if (skbs == NULL) { | ||
| 91 | ipath_dev_err(dd, "allocation error for eager TID " | ||
| 92 | "skb array\n"); | ||
| 93 | ret = -ENOMEM; | ||
| 94 | goto bail; | ||
| 95 | } | ||
| 96 | for (e = 0; e < egrcnt; e++) { | ||
| 97 | /* | ||
| 98 | * This is a bit tricky in that we allocate extra | ||
| 99 | * space for 2 bytes of the 14 byte ethernet header. | ||
| 100 | * These two bytes are passed in the ipath header so | ||
| 101 | * the rest of the data is word aligned. We allocate | ||
| 102 | * 4 bytes so that the data buffer stays word aligned. | ||
| 103 | * See ipath_kreceive() for more details. | ||
| 104 | */ | ||
| 105 | skbs[e] = ipath_alloc_skb(dd, GFP_KERNEL); | ||
| 106 | if (!skbs[e]) { | ||
| 107 | ipath_dev_err(dd, "SKB allocation error for " | ||
| 108 | "eager TID %u\n", e); | ||
| 109 | while (e != 0) | ||
| 110 | dev_kfree_skb(skbs[--e]); | ||
| 111 | ret = -ENOMEM; | ||
| 112 | goto bail; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | /* | ||
| 116 | * After loop above, so we can test non-NULL to see if ready | ||
| 117 | * to use at receive, etc. | ||
| 118 | */ | ||
| 119 | dd->ipath_port0_skbs = skbs; | ||
| 120 | |||
| 121 | for (e = 0; e < egrcnt; e++) { | ||
| 122 | unsigned long phys = | ||
| 123 | virt_to_phys(dd->ipath_port0_skbs[e]->data); | ||
| 124 | dd->ipath_f_put_tid(dd, e + (u64 __iomem *) | ||
| 125 | ((char __iomem *) dd->ipath_kregbase + | ||
| 126 | dd->ipath_rcvegrbase), 0, phys); | ||
| 127 | } | ||
| 128 | |||
| 129 | ret = 0; | ||
| 130 | |||
| 131 | bail: | ||
| 132 | return ret; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int bringup_link(struct ipath_devdata *dd) | ||
| 136 | { | ||
| 137 | u64 val, ibc; | ||
| 138 | int ret = 0; | ||
| 139 | |||
| 140 | /* hold IBC in reset */ | ||
| 141 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; | ||
| 142 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 143 | dd->ipath_control); | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Note that prior to try 14 or 15 of IB, the credit scaling | ||
| 147 | * wasn't working, because it was swapped for writes with the | ||
| 148 | * 1 bit default linkstate field | ||
| 149 | */ | ||
| 150 | |||
| 151 | /* ignore pbc and align word */ | ||
| 152 | val = dd->ipath_piosize2k - 2 * sizeof(u32); | ||
| 153 | /* | ||
| 154 | * for ICRC, which we only send in diag test pkt mode, and we | ||
| 155 | * don't need to worry about that for mtu | ||
| 156 | */ | ||
| 157 | val += 1; | ||
| 158 | /* | ||
| 159 | * Set the IBC maxpktlength to the size of our pio buffers the | ||
| 160 | * maxpktlength is in words. This is *not* the IB data MTU. | ||
| 161 | */ | ||
| 162 | ibc = (val / sizeof(u32)) << INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
| 163 | /* in KB */ | ||
| 164 | ibc |= 0x5ULL << INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT; | ||
| 165 | /* | ||
| 166 | * How often flowctrl sent. More or less in usecs; balance against | ||
| 167 | * watermark value, so that in theory senders always get a flow | ||
| 168 | * control update in time to not let the IB link go idle. | ||
| 169 | */ | ||
| 170 | ibc |= 0x3ULL << INFINIPATH_IBCC_FLOWCTRLPERIOD_SHIFT; | ||
| 171 | /* max error tolerance */ | ||
| 172 | ibc |= 0xfULL << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT; | ||
| 173 | /* use "real" buffer space for */ | ||
| 174 | ibc |= 4ULL << INFINIPATH_IBCC_CREDITSCALE_SHIFT; | ||
| 175 | /* IB credit flow control. */ | ||
| 176 | ibc |= 0xfULL << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT; | ||
| 177 | /* initially come up waiting for TS1, without sending anything. */ | ||
| 178 | dd->ipath_ibcctrl = ibc; | ||
| 179 | /* | ||
| 180 | * Want to start out with both LINKCMD and LINKINITCMD in NOP | ||
| 181 | * (0 and 0). Don't put linkinitcmd in ipath_ibcctrl, want that | ||
| 182 | * to stay a NOP | ||
| 183 | */ | ||
| 184 | ibc |= INFINIPATH_IBCC_LINKINITCMD_DISABLE << | ||
| 185 | INFINIPATH_IBCC_LINKINITCMD_SHIFT; | ||
| 186 | ipath_cdbg(VERBOSE, "Writing 0x%llx to ibcctrl\n", | ||
| 187 | (unsigned long long) ibc); | ||
| 188 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, ibc); | ||
| 189 | |||
| 190 | // be sure chip saw it | ||
| 191 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 192 | |||
| 193 | ret = dd->ipath_f_bringup_serdes(dd); | ||
| 194 | |||
| 195 | if (ret) | ||
| 196 | dev_info(&dd->pcidev->dev, "Could not initialize SerDes, " | ||
| 197 | "not usable\n"); | ||
| 198 | else { | ||
| 199 | /* enable IBC */ | ||
| 200 | dd->ipath_control |= INFINIPATH_C_LINKENABLE; | ||
| 201 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 202 | dd->ipath_control); | ||
| 203 | } | ||
| 204 | |||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | |||
| 208 | static int init_chip_first(struct ipath_devdata *dd, | ||
| 209 | struct ipath_portdata **pdp) | ||
| 210 | { | ||
| 211 | struct ipath_portdata *pd = NULL; | ||
| 212 | int ret = 0; | ||
| 213 | u64 val; | ||
| 214 | |||
| 215 | /* | ||
| 216 | * skip cfgports stuff because we are not allocating memory, | ||
| 217 | * and we don't want problems if the portcnt changed due to | ||
| 218 | * cfgports. We do still check and report a difference, if | ||
| 219 | * not same (should be impossible). | ||
| 220 | */ | ||
| 221 | dd->ipath_portcnt = | ||
| 222 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
| 223 | if (!ipath_cfgports) | ||
| 224 | dd->ipath_cfgports = dd->ipath_portcnt; | ||
| 225 | else if (ipath_cfgports <= dd->ipath_portcnt) { | ||
| 226 | dd->ipath_cfgports = ipath_cfgports; | ||
| 227 | ipath_dbg("Configured to use %u ports out of %u in chip\n", | ||
| 228 | dd->ipath_cfgports, dd->ipath_portcnt); | ||
| 229 | } else { | ||
| 230 | dd->ipath_cfgports = dd->ipath_portcnt; | ||
| 231 | ipath_dbg("Tried to configured to use %u ports; chip " | ||
| 232 | "only supports %u\n", ipath_cfgports, | ||
| 233 | dd->ipath_portcnt); | ||
| 234 | } | ||
| 235 | dd->ipath_pd = kzalloc(sizeof(*dd->ipath_pd) * dd->ipath_cfgports, | ||
| 236 | GFP_KERNEL); | ||
| 237 | |||
| 238 | if (!dd->ipath_pd) { | ||
| 239 | ipath_dev_err(dd, "Unable to allocate portdata array, " | ||
| 240 | "failing\n"); | ||
| 241 | ret = -ENOMEM; | ||
| 242 | goto done; | ||
| 243 | } | ||
| 244 | |||
| 245 | dd->ipath_lastegrheads = kzalloc(sizeof(*dd->ipath_lastegrheads) | ||
| 246 | * dd->ipath_cfgports, | ||
| 247 | GFP_KERNEL); | ||
| 248 | dd->ipath_lastrcvhdrqtails = | ||
| 249 | kzalloc(sizeof(*dd->ipath_lastrcvhdrqtails) | ||
| 250 | * dd->ipath_cfgports, GFP_KERNEL); | ||
| 251 | |||
| 252 | if (!dd->ipath_lastegrheads || !dd->ipath_lastrcvhdrqtails) { | ||
| 253 | ipath_dev_err(dd, "Unable to allocate head arrays, " | ||
| 254 | "failing\n"); | ||
| 255 | ret = -ENOMEM; | ||
| 256 | goto done; | ||
| 257 | } | ||
| 258 | |||
| 259 | dd->ipath_pd[0] = kzalloc(sizeof(*pd), GFP_KERNEL); | ||
| 260 | |||
| 261 | if (!dd->ipath_pd[0]) { | ||
| 262 | ipath_dev_err(dd, "Unable to allocate portdata for port " | ||
| 263 | "0, failing\n"); | ||
| 264 | ret = -ENOMEM; | ||
| 265 | goto done; | ||
| 266 | } | ||
| 267 | pd = dd->ipath_pd[0]; | ||
| 268 | pd->port_dd = dd; | ||
| 269 | pd->port_port = 0; | ||
| 270 | pd->port_cnt = 1; | ||
| 271 | /* The port 0 pkey table is used by the layer interface. */ | ||
| 272 | pd->port_pkeys[0] = IPS_DEFAULT_P_KEY; | ||
| 273 | dd->ipath_rcvtidcnt = | ||
| 274 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); | ||
| 275 | dd->ipath_rcvtidbase = | ||
| 276 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidbase); | ||
| 277 | dd->ipath_rcvegrcnt = | ||
| 278 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
| 279 | dd->ipath_rcvegrbase = | ||
| 280 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrbase); | ||
| 281 | dd->ipath_palign = | ||
| 282 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign); | ||
| 283 | dd->ipath_piobufbase = | ||
| 284 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufbase); | ||
| 285 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiosize); | ||
| 286 | dd->ipath_piosize2k = val & ~0U; | ||
| 287 | dd->ipath_piosize4k = val >> 32; | ||
| 288 | dd->ipath_ibmtu = 4096; /* default to largest legal MTU */ | ||
| 289 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpiobufcnt); | ||
| 290 | dd->ipath_piobcnt2k = val & ~0U; | ||
| 291 | dd->ipath_piobcnt4k = val >> 32; | ||
| 292 | dd->ipath_pio2kbase = | ||
| 293 | (u32 __iomem *) (((char __iomem *) dd->ipath_kregbase) + | ||
| 294 | (dd->ipath_piobufbase & 0xffffffff)); | ||
| 295 | if (dd->ipath_piobcnt4k) { | ||
| 296 | dd->ipath_pio4kbase = (u32 __iomem *) | ||
| 297 | (((char __iomem *) dd->ipath_kregbase) + | ||
| 298 | (dd->ipath_piobufbase >> 32)); | ||
| 299 | /* | ||
| 300 | * 4K buffers take 2 pages; we use roundup just to be | ||
| 301 | * paranoid; we calculate it once here, rather than on | ||
| 302 | * ever buf allocate | ||
| 303 | */ | ||
| 304 | dd->ipath_4kalign = ALIGN(dd->ipath_piosize4k, | ||
| 305 | dd->ipath_palign); | ||
| 306 | ipath_dbg("%u 2k(%x) piobufs @ %p, %u 4k(%x) @ %p " | ||
| 307 | "(%x aligned)\n", | ||
| 308 | dd->ipath_piobcnt2k, dd->ipath_piosize2k, | ||
| 309 | dd->ipath_pio2kbase, dd->ipath_piobcnt4k, | ||
| 310 | dd->ipath_piosize4k, dd->ipath_pio4kbase, | ||
| 311 | dd->ipath_4kalign); | ||
| 312 | } | ||
| 313 | else ipath_dbg("%u 2k piobufs @ %p\n", | ||
| 314 | dd->ipath_piobcnt2k, dd->ipath_pio2kbase); | ||
| 315 | |||
| 316 | spin_lock_init(&dd->ipath_tid_lock); | ||
| 317 | |||
| 318 | done: | ||
| 319 | *pdp = pd; | ||
| 320 | return ret; | ||
| 321 | } | ||
| 322 | |||
| 323 | /** | ||
| 324 | * init_chip_reset - re-initialize after a reset, or enable | ||
| 325 | * @dd: the infinipath device | ||
| 326 | * @pdp: output for port data | ||
| 327 | * | ||
| 328 | * sanity check at least some of the values after reset, and | ||
| 329 | * ensure no receive or transmit (explictly, in case reset | ||
| 330 | * failed | ||
| 331 | */ | ||
| 332 | static int init_chip_reset(struct ipath_devdata *dd, | ||
| 333 | struct ipath_portdata **pdp) | ||
| 334 | { | ||
| 335 | struct ipath_portdata *pd; | ||
| 336 | u32 rtmp; | ||
| 337 | |||
| 338 | *pdp = pd = dd->ipath_pd[0]; | ||
| 339 | /* ensure chip does no sends or receives while we re-initialize */ | ||
| 340 | dd->ipath_control = dd->ipath_sendctrl = dd->ipath_rcvctrl = 0U; | ||
| 341 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 0); | ||
| 342 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 0); | ||
| 343 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0); | ||
| 344 | |||
| 345 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
| 346 | if (dd->ipath_portcnt != rtmp) | ||
| 347 | dev_info(&dd->pcidev->dev, "portcnt was %u before " | ||
| 348 | "reset, now %u, using original\n", | ||
| 349 | dd->ipath_portcnt, rtmp); | ||
| 350 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidcnt); | ||
| 351 | if (rtmp != dd->ipath_rcvtidcnt) | ||
| 352 | dev_info(&dd->pcidev->dev, "tidcnt was %u before " | ||
| 353 | "reset, now %u, using original\n", | ||
| 354 | dd->ipath_rcvtidcnt, rtmp); | ||
| 355 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvtidbase); | ||
| 356 | if (rtmp != dd->ipath_rcvtidbase) | ||
| 357 | dev_info(&dd->pcidev->dev, "tidbase was %u before " | ||
| 358 | "reset, now %u, using original\n", | ||
| 359 | dd->ipath_rcvtidbase, rtmp); | ||
| 360 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
| 361 | if (rtmp != dd->ipath_rcvegrcnt) | ||
| 362 | dev_info(&dd->pcidev->dev, "egrcnt was %u before " | ||
| 363 | "reset, now %u, using original\n", | ||
| 364 | dd->ipath_rcvegrcnt, rtmp); | ||
| 365 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrbase); | ||
| 366 | if (rtmp != dd->ipath_rcvegrbase) | ||
| 367 | dev_info(&dd->pcidev->dev, "egrbase was %u before " | ||
| 368 | "reset, now %u, using original\n", | ||
| 369 | dd->ipath_rcvegrbase, rtmp); | ||
| 370 | |||
| 371 | return 0; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int init_pioavailregs(struct ipath_devdata *dd) | ||
| 375 | { | ||
| 376 | int ret; | ||
| 377 | |||
| 378 | dd->ipath_pioavailregs_dma = dma_alloc_coherent( | ||
| 379 | &dd->pcidev->dev, PAGE_SIZE, &dd->ipath_pioavailregs_phys, | ||
| 380 | GFP_KERNEL); | ||
| 381 | if (!dd->ipath_pioavailregs_dma) { | ||
| 382 | ipath_dev_err(dd, "failed to allocate PIOavail reg area " | ||
| 383 | "in memory\n"); | ||
| 384 | ret = -ENOMEM; | ||
| 385 | goto done; | ||
| 386 | } | ||
| 387 | |||
| 388 | /* | ||
| 389 | * we really want L2 cache aligned, but for current CPUs of | ||
| 390 | * interest, they are the same. | ||
| 391 | */ | ||
| 392 | dd->ipath_statusp = (u64 *) | ||
| 393 | ((char *)dd->ipath_pioavailregs_dma + | ||
| 394 | ((2 * L1_CACHE_BYTES + | ||
| 395 | dd->ipath_pioavregs * sizeof(u64)) & ~L1_CACHE_BYTES)); | ||
| 396 | /* copy the current value now that it's really allocated */ | ||
| 397 | *dd->ipath_statusp = dd->_ipath_status; | ||
| 398 | /* | ||
| 399 | * setup buffer to hold freeze msg, accessible to apps, | ||
| 400 | * following statusp | ||
| 401 | */ | ||
| 402 | dd->ipath_freezemsg = (char *)&dd->ipath_statusp[1]; | ||
| 403 | /* and its length */ | ||
| 404 | dd->ipath_freezelen = L1_CACHE_BYTES - sizeof(dd->ipath_statusp[0]); | ||
| 405 | |||
| 406 | if (dd->ipath_unit * 64 > (IPATH_PORT0_RCVHDRTAIL_SIZE - 64)) { | ||
| 407 | ipath_dev_err(dd, "unit %u too large for port 0 " | ||
| 408 | "rcvhdrtail buffer size\n", dd->ipath_unit); | ||
| 409 | ret = -ENODEV; | ||
| 410 | } | ||
| 411 | else | ||
| 412 | ret = 0; | ||
| 413 | |||
| 414 | /* so we can get current tail in ipath_kreceive(), per chip */ | ||
| 415 | dd->ipath_hdrqtailptr = &ipath_port0_rcvhdrtail[ | ||
| 416 | dd->ipath_unit * (64 / sizeof(*ipath_port0_rcvhdrtail))]; | ||
| 417 | done: | ||
| 418 | return ret; | ||
| 419 | } | ||
| 420 | |||
| 421 | /** | ||
| 422 | * init_shadow_tids - allocate the shadow TID array | ||
| 423 | * @dd: the infinipath device | ||
| 424 | * | ||
| 425 | * allocate the shadow TID array, so we can ipath_munlock previous | ||
| 426 | * entries. It may make more sense to move the pageshadow to the | ||
| 427 | * port data structure, so we only allocate memory for ports actually | ||
| 428 | * in use, since we at 8k per port, now. | ||
| 429 | */ | ||
| 430 | static void init_shadow_tids(struct ipath_devdata *dd) | ||
| 431 | { | ||
| 432 | dd->ipath_pageshadow = (struct page **) | ||
| 433 | vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt * | ||
| 434 | sizeof(struct page *)); | ||
| 435 | if (!dd->ipath_pageshadow) | ||
| 436 | ipath_dev_err(dd, "failed to allocate shadow page * " | ||
| 437 | "array, no expected sends!\n"); | ||
| 438 | else | ||
| 439 | memset(dd->ipath_pageshadow, 0, | ||
| 440 | dd->ipath_cfgports * dd->ipath_rcvtidcnt * | ||
| 441 | sizeof(struct page *)); | ||
| 442 | } | ||
| 443 | |||
| 444 | static void enable_chip(struct ipath_devdata *dd, | ||
| 445 | struct ipath_portdata *pd, int reinit) | ||
| 446 | { | ||
| 447 | u32 val; | ||
| 448 | int i; | ||
| 449 | |||
| 450 | if (!reinit) { | ||
| 451 | init_waitqueue_head(&ipath_sma_state_wait); | ||
| 452 | } | ||
| 453 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 454 | dd->ipath_rcvctrl); | ||
| 455 | |||
| 456 | /* Enable PIO send, and update of PIOavail regs to memory. */ | ||
| 457 | dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE | | ||
| 458 | INFINIPATH_S_PIOBUFAVAILUPD; | ||
| 459 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 460 | dd->ipath_sendctrl); | ||
| 461 | |||
| 462 | /* | ||
| 463 | * enable port 0 receive, and receive interrupt. other ports | ||
| 464 | * done as user opens and inits them. | ||
| 465 | */ | ||
| 466 | dd->ipath_rcvctrl = INFINIPATH_R_TAILUPD | | ||
| 467 | (1ULL << INFINIPATH_R_PORTENABLE_SHIFT) | | ||
| 468 | (1ULL << INFINIPATH_R_INTRAVAIL_SHIFT); | ||
| 469 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 470 | dd->ipath_rcvctrl); | ||
| 471 | |||
| 472 | /* | ||
| 473 | * now ready for use. this should be cleared whenever we | ||
| 474 | * detect a reset, or initiate one. | ||
| 475 | */ | ||
| 476 | dd->ipath_flags |= IPATH_INITTED; | ||
| 477 | |||
| 478 | /* | ||
| 479 | * init our shadow copies of head from tail values, and write | ||
| 480 | * head values to match. | ||
| 481 | */ | ||
| 482 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); | ||
| 483 | (void)ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); | ||
| 484 | dd->ipath_port0head = ipath_read_ureg32(dd, ur_rcvhdrtail, 0); | ||
| 485 | |||
| 486 | /* Initialize so we interrupt on next packet received */ | ||
| 487 | (void)ipath_write_ureg(dd, ur_rcvhdrhead, | ||
| 488 | dd->ipath_rhdrhead_intr_off | | ||
| 489 | dd->ipath_port0head, 0); | ||
| 490 | |||
| 491 | /* | ||
| 492 | * by now pioavail updates to memory should have occurred, so | ||
| 493 | * copy them into our working/shadow registers; this is in | ||
| 494 | * case something went wrong with abort, but mostly to get the | ||
| 495 | * initial values of the generation bit correct. | ||
| 496 | */ | ||
| 497 | for (i = 0; i < dd->ipath_pioavregs; i++) { | ||
| 498 | __le64 val; | ||
| 499 | |||
| 500 | /* | ||
| 501 | * Chip Errata bug 6641; even and odd qwords>3 are swapped. | ||
| 502 | */ | ||
| 503 | if (i > 3) { | ||
| 504 | if (i & 1) | ||
| 505 | val = dd->ipath_pioavailregs_dma[i - 1]; | ||
| 506 | else | ||
| 507 | val = dd->ipath_pioavailregs_dma[i + 1]; | ||
| 508 | } | ||
| 509 | else | ||
| 510 | val = dd->ipath_pioavailregs_dma[i]; | ||
| 511 | dd->ipath_pioavailshadow[i] = le64_to_cpu(val); | ||
| 512 | } | ||
| 513 | /* can get counters, stats, etc. */ | ||
| 514 | dd->ipath_flags |= IPATH_PRESENT; | ||
| 515 | } | ||
| 516 | |||
| 517 | static int init_housekeeping(struct ipath_devdata *dd, | ||
| 518 | struct ipath_portdata **pdp, int reinit) | ||
| 519 | { | ||
| 520 | char boardn[32]; | ||
| 521 | int ret = 0; | ||
| 522 | |||
| 523 | /* | ||
| 524 | * have to clear shadow copies of registers at init that are | ||
| 525 | * not otherwise set here, or all kinds of bizarre things | ||
| 526 | * happen with driver on chip reset | ||
| 527 | */ | ||
| 528 | dd->ipath_rcvhdrsize = 0; | ||
| 529 | |||
| 530 | /* | ||
| 531 | * Don't clear ipath_flags as 8bit mode was set before | ||
| 532 | * entering this func. However, we do set the linkstate to | ||
| 533 | * unknown, so we can watch for a transition. | ||
| 534 | */ | ||
| 535 | dd->ipath_flags |= IPATH_LINKUNK; | ||
| 536 | dd->ipath_flags &= ~(IPATH_LINKACTIVE | IPATH_LINKARMED | | ||
| 537 | IPATH_LINKDOWN | IPATH_LINKINIT); | ||
| 538 | |||
| 539 | ipath_cdbg(VERBOSE, "Try to read spc chip revision\n"); | ||
| 540 | dd->ipath_revision = | ||
| 541 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); | ||
| 542 | |||
| 543 | /* | ||
| 544 | * set up fundamental info we need to use the chip; we assume | ||
| 545 | * if the revision reg and these regs are OK, we don't need to | ||
| 546 | * special case the rest | ||
| 547 | */ | ||
| 548 | dd->ipath_sregbase = | ||
| 549 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_sendregbase); | ||
| 550 | dd->ipath_cregbase = | ||
| 551 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_counterregbase); | ||
| 552 | dd->ipath_uregbase = | ||
| 553 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_userregbase); | ||
| 554 | ipath_cdbg(VERBOSE, "ipath_kregbase %p, sendbase %x usrbase %x, " | ||
| 555 | "cntrbase %x\n", dd->ipath_kregbase, dd->ipath_sregbase, | ||
| 556 | dd->ipath_uregbase, dd->ipath_cregbase); | ||
| 557 | if ((dd->ipath_revision & 0xffffffff) == 0xffffffff | ||
| 558 | || (dd->ipath_sregbase & 0xffffffff) == 0xffffffff | ||
| 559 | || (dd->ipath_cregbase & 0xffffffff) == 0xffffffff | ||
| 560 | || (dd->ipath_uregbase & 0xffffffff) == 0xffffffff) { | ||
| 561 | ipath_dev_err(dd, "Register read failures from chip, " | ||
| 562 | "giving up initialization\n"); | ||
| 563 | ret = -ENODEV; | ||
| 564 | goto done; | ||
| 565 | } | ||
| 566 | |||
| 567 | /* clear the initial reset flag, in case first driver load */ | ||
| 568 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, | ||
| 569 | INFINIPATH_E_RESET); | ||
| 570 | |||
| 571 | if (reinit) | ||
| 572 | ret = init_chip_reset(dd, pdp); | ||
| 573 | else | ||
| 574 | ret = init_chip_first(dd, pdp); | ||
| 575 | |||
| 576 | if (ret) | ||
| 577 | goto done; | ||
| 578 | |||
| 579 | ipath_cdbg(VERBOSE, "Revision %llx (PCI %x), %u ports, %u tids, " | ||
| 580 | "%u egrtids\n", (unsigned long long) dd->ipath_revision, | ||
| 581 | dd->ipath_pcirev, dd->ipath_portcnt, dd->ipath_rcvtidcnt, | ||
| 582 | dd->ipath_rcvegrcnt); | ||
| 583 | |||
| 584 | if (((dd->ipath_revision >> INFINIPATH_R_SOFTWARE_SHIFT) & | ||
| 585 | INFINIPATH_R_SOFTWARE_MASK) != IPATH_CHIP_SWVERSION) { | ||
| 586 | ipath_dev_err(dd, "Driver only handles version %d, " | ||
| 587 | "chip swversion is %d (%llx), failng\n", | ||
| 588 | IPATH_CHIP_SWVERSION, | ||
| 589 | (int)(dd->ipath_revision >> | ||
| 590 | INFINIPATH_R_SOFTWARE_SHIFT) & | ||
| 591 | INFINIPATH_R_SOFTWARE_MASK, | ||
| 592 | (unsigned long long) dd->ipath_revision); | ||
| 593 | ret = -ENOSYS; | ||
| 594 | goto done; | ||
| 595 | } | ||
| 596 | dd->ipath_majrev = (u8) ((dd->ipath_revision >> | ||
| 597 | INFINIPATH_R_CHIPREVMAJOR_SHIFT) & | ||
| 598 | INFINIPATH_R_CHIPREVMAJOR_MASK); | ||
| 599 | dd->ipath_minrev = (u8) ((dd->ipath_revision >> | ||
| 600 | INFINIPATH_R_CHIPREVMINOR_SHIFT) & | ||
| 601 | INFINIPATH_R_CHIPREVMINOR_MASK); | ||
| 602 | dd->ipath_boardrev = (u8) ((dd->ipath_revision >> | ||
| 603 | INFINIPATH_R_BOARDID_SHIFT) & | ||
| 604 | INFINIPATH_R_BOARDID_MASK); | ||
| 605 | |||
| 606 | ret = dd->ipath_f_get_boardname(dd, boardn, sizeof boardn); | ||
| 607 | |||
| 608 | snprintf(dd->ipath_boardversion, sizeof(dd->ipath_boardversion), | ||
| 609 | "Driver %u.%u, %s, InfiniPath%u %u.%u, PCI %u, " | ||
| 610 | "SW Compat %u\n", | ||
| 611 | IPATH_CHIP_VERS_MAJ, IPATH_CHIP_VERS_MIN, boardn, | ||
| 612 | (unsigned)(dd->ipath_revision >> INFINIPATH_R_ARCH_SHIFT) & | ||
| 613 | INFINIPATH_R_ARCH_MASK, | ||
| 614 | dd->ipath_majrev, dd->ipath_minrev, dd->ipath_pcirev, | ||
| 615 | (unsigned)(dd->ipath_revision >> | ||
| 616 | INFINIPATH_R_SOFTWARE_SHIFT) & | ||
| 617 | INFINIPATH_R_SOFTWARE_MASK); | ||
| 618 | |||
| 619 | ipath_dbg("%s", dd->ipath_boardversion); | ||
| 620 | |||
| 621 | done: | ||
| 622 | return ret; | ||
| 623 | } | ||
| 624 | |||
| 625 | |||
| 626 | /** | ||
| 627 | * ipath_init_chip - do the actual initialization sequence on the chip | ||
| 628 | * @dd: the infinipath device | ||
| 629 | * @reinit: reinitializing, so don't allocate new memory | ||
| 630 | * | ||
| 631 | * Do the actual initialization sequence on the chip. This is done | ||
| 632 | * both from the init routine called from the PCI infrastructure, and | ||
| 633 | * when we reset the chip, or detect that it was reset internally, | ||
| 634 | * or it's administratively re-enabled. | ||
| 635 | * | ||
| 636 | * Memory allocation here and in called routines is only done in | ||
| 637 | * the first case (reinit == 0). We have to be careful, because even | ||
| 638 | * without memory allocation, we need to re-write all the chip registers | ||
| 639 | * TIDs, etc. after the reset or enable has completed. | ||
| 640 | */ | ||
| 641 | int ipath_init_chip(struct ipath_devdata *dd, int reinit) | ||
| 642 | { | ||
| 643 | int ret = 0, i; | ||
| 644 | u32 val32, kpiobufs; | ||
| 645 | u64 val, atmp; | ||
| 646 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ | ||
| 647 | |||
| 648 | ret = init_housekeeping(dd, &pd, reinit); | ||
| 649 | if (ret) | ||
| 650 | goto done; | ||
| 651 | |||
| 652 | /* | ||
| 653 | * we ignore most issues after reporting them, but have to specially | ||
| 654 | * handle hardware-disabled chips. | ||
| 655 | */ | ||
| 656 | if (ret == 2) { | ||
| 657 | /* unique error, known to ipath_init_one */ | ||
| 658 | ret = -EPERM; | ||
| 659 | goto done; | ||
| 660 | } | ||
| 661 | |||
| 662 | /* | ||
| 663 | * We could bump this to allow for full rcvegrcnt + rcvtidcnt, | ||
| 664 | * but then it no longer nicely fits power of two, and since | ||
| 665 | * we now use routines that backend onto __get_free_pages, the | ||
| 666 | * rest would be wasted. | ||
| 667 | */ | ||
| 668 | dd->ipath_rcvhdrcnt = dd->ipath_rcvegrcnt; | ||
| 669 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrcnt, | ||
| 670 | dd->ipath_rcvhdrcnt); | ||
| 671 | |||
| 672 | /* | ||
| 673 | * Set up the shadow copies of the piobufavail registers, | ||
| 674 | * which we compare against the chip registers for now, and | ||
| 675 | * the in memory DMA'ed copies of the registers. This has to | ||
| 676 | * be done early, before we calculate lastport, etc. | ||
| 677 | */ | ||
| 678 | val = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; | ||
| 679 | /* | ||
| 680 | * calc number of pioavail registers, and save it; we have 2 | ||
| 681 | * bits per buffer. | ||
| 682 | */ | ||
| 683 | dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) | ||
| 684 | / (sizeof(u64) * BITS_PER_BYTE / 2); | ||
| 685 | if (!ipath_kpiobufs) /* have to have at least 1, for SMA */ | ||
| 686 | kpiobufs = ipath_kpiobufs = 1; | ||
| 687 | else if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) < | ||
| 688 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT)) { | ||
| 689 | dev_info(&dd->pcidev->dev, "Too few PIO buffers (%u) " | ||
| 690 | "for %u ports to have %u each!\n", | ||
| 691 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | ||
| 692 | dd->ipath_cfgports, IPATH_MIN_USER_PORT_BUFCNT); | ||
| 693 | kpiobufs = 1; /* reserve just the minimum for SMA/ether */ | ||
| 694 | } else | ||
| 695 | kpiobufs = ipath_kpiobufs; | ||
| 696 | |||
| 697 | if (kpiobufs > | ||
| 698 | (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
| 699 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT))) { | ||
| 700 | i = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
| 701 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT); | ||
| 702 | if (i < 0) | ||
| 703 | i = 0; | ||
| 704 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs for " | ||
| 705 | "kernel leaves too few for %d user ports " | ||
| 706 | "(%d each); using %u\n", kpiobufs, | ||
| 707 | dd->ipath_cfgports - 1, | ||
| 708 | IPATH_MIN_USER_PORT_BUFCNT, i); | ||
| 709 | /* | ||
| 710 | * shouldn't change ipath_kpiobufs, because could be | ||
| 711 | * different for different devices... | ||
| 712 | */ | ||
| 713 | kpiobufs = i; | ||
| 714 | } | ||
| 715 | dd->ipath_lastport_piobuf = | ||
| 716 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - kpiobufs; | ||
| 717 | dd->ipath_pbufsport = dd->ipath_cfgports > 1 | ||
| 718 | ? dd->ipath_lastport_piobuf / (dd->ipath_cfgports - 1) | ||
| 719 | : 0; | ||
| 720 | val32 = dd->ipath_lastport_piobuf - | ||
| 721 | (dd->ipath_pbufsport * (dd->ipath_cfgports - 1)); | ||
| 722 | if (val32 > 0) { | ||
| 723 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " | ||
| 724 | "add to kernel\n", dd->ipath_pbufsport, val32); | ||
| 725 | dd->ipath_lastport_piobuf -= val32; | ||
| 726 | ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", | ||
| 727 | dd->ipath_pbufsport, val32); | ||
| 728 | } | ||
| 729 | dd->ipath_lastpioindex = dd->ipath_lastport_piobuf; | ||
| 730 | ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " | ||
| 731 | "each for %u user ports\n", kpiobufs, | ||
| 732 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | ||
| 733 | dd->ipath_pbufsport, dd->ipath_cfgports - 1); | ||
| 734 | |||
| 735 | dd->ipath_f_early_init(dd); | ||
| 736 | |||
| 737 | /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be | ||
| 738 | * done after early_init */ | ||
| 739 | dd->ipath_hdrqlast = | ||
| 740 | dd->ipath_rcvhdrentsize * (dd->ipath_rcvhdrcnt - 1); | ||
| 741 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrentsize, | ||
| 742 | dd->ipath_rcvhdrentsize); | ||
| 743 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvhdrsize, | ||
| 744 | dd->ipath_rcvhdrsize); | ||
| 745 | |||
| 746 | if (!reinit) { | ||
| 747 | ret = init_pioavailregs(dd); | ||
| 748 | init_shadow_tids(dd); | ||
| 749 | if (ret) | ||
| 750 | goto done; | ||
| 751 | } | ||
| 752 | |||
| 753 | (void)ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr, | ||
| 754 | dd->ipath_pioavailregs_phys); | ||
| 755 | /* | ||
| 756 | * this is to detect s/w errors, which the h/w works around by | ||
| 757 | * ignoring the low 6 bits of address, if it wasn't aligned. | ||
| 758 | */ | ||
| 759 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_sendpioavailaddr); | ||
| 760 | if (val != dd->ipath_pioavailregs_phys) { | ||
| 761 | ipath_dev_err(dd, "Catastrophic software error, " | ||
| 762 | "SendPIOAvailAddr written as %lx, " | ||
| 763 | "read back as %llx\n", | ||
| 764 | (unsigned long) dd->ipath_pioavailregs_phys, | ||
| 765 | (unsigned long long) val); | ||
| 766 | ret = -EINVAL; | ||
| 767 | goto done; | ||
| 768 | } | ||
| 769 | |||
| 770 | val = ipath_port0_rcvhdrtail_dma + dd->ipath_unit * 64; | ||
| 771 | |||
| 772 | /* verify that the alignment requirement was met */ | ||
| 773 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdrtailaddr, | ||
| 774 | 0, val); | ||
| 775 | atmp = ipath_read_kreg64_port( | ||
| 776 | dd, dd->ipath_kregs->kr_rcvhdrtailaddr, 0); | ||
| 777 | if (val != atmp) { | ||
| 778 | ipath_dev_err(dd, "Catastrophic software error, " | ||
| 779 | "RcvHdrTailAddr0 written as %llx, " | ||
| 780 | "read back as %llx from %x\n", | ||
| 781 | (unsigned long long) val, | ||
| 782 | (unsigned long long) atmp, | ||
| 783 | dd->ipath_kregs->kr_rcvhdrtailaddr); | ||
| 784 | ret = -EINVAL; | ||
| 785 | goto done; | ||
| 786 | } | ||
| 787 | |||
| 788 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvbthqp, IPATH_KD_QP); | ||
| 789 | |||
| 790 | /* | ||
| 791 | * make sure we are not in freeze, and PIO send enabled, so | ||
| 792 | * writes to pbc happen | ||
| 793 | */ | ||
| 794 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, 0ULL); | ||
| 795 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 796 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); | ||
| 797 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); | ||
| 798 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 799 | INFINIPATH_S_PIOENABLE); | ||
| 800 | |||
| 801 | /* | ||
| 802 | * before error clears, since we expect serdes pll errors during | ||
| 803 | * this, the first time after reset | ||
| 804 | */ | ||
| 805 | if (bringup_link(dd)) { | ||
| 806 | dev_info(&dd->pcidev->dev, "Failed to bringup IB link\n"); | ||
| 807 | ret = -ENETDOWN; | ||
| 808 | goto done; | ||
| 809 | } | ||
| 810 | |||
| 811 | /* | ||
| 812 | * clear any "expected" hwerrs from reset and/or initialization | ||
| 813 | * clear any that aren't enabled (at least this once), and then | ||
| 814 | * set the enable mask | ||
| 815 | */ | ||
| 816 | dd->ipath_f_init_hwerrors(dd); | ||
| 817 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 818 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); | ||
| 819 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 820 | dd->ipath_hwerrmask); | ||
| 821 | |||
| 822 | dd->ipath_maskederrs = dd->ipath_ignorederrs; | ||
| 823 | /* clear all */ | ||
| 824 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); | ||
| 825 | /* enable errors that are masked, at least this first time. */ | ||
| 826 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
| 827 | ~dd->ipath_maskederrs); | ||
| 828 | /* clear any interrups up to this point (ints still not enabled) */ | ||
| 829 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); | ||
| 830 | |||
| 831 | ipath_stats.sps_lid[dd->ipath_unit] = dd->ipath_lid; | ||
| 832 | |||
| 833 | /* | ||
| 834 | * Set up the port 0 (kernel) rcvhdr q and egr TIDs. If doing | ||
| 835 | * re-init, the simplest way to handle this is to free | ||
| 836 | * existing, and re-allocate. | ||
| 837 | */ | ||
| 838 | if (reinit) | ||
| 839 | ipath_free_pddata(dd, 0, 0); | ||
| 840 | dd->ipath_f_tidtemplate(dd); | ||
| 841 | ret = ipath_create_rcvhdrq(dd, pd); | ||
| 842 | if (!ret) | ||
| 843 | ret = create_port0_egr(dd); | ||
| 844 | if (ret) | ||
| 845 | ipath_dev_err(dd, "failed to allocate port 0 (kernel) " | ||
| 846 | "rcvhdrq and/or egr bufs\n"); | ||
| 847 | else | ||
| 848 | enable_chip(dd, pd, reinit); | ||
| 849 | |||
| 850 | /* | ||
| 851 | * cause retrigger of pending interrupts ignored during init, | ||
| 852 | * even if we had errors | ||
| 853 | */ | ||
| 854 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); | ||
| 855 | |||
| 856 | if(!dd->ipath_stats_timer_active) { | ||
| 857 | /* | ||
| 858 | * first init, or after an admin disable/enable | ||
| 859 | * set up stats retrieval timer, even if we had errors | ||
| 860 | * in last portion of setup | ||
| 861 | */ | ||
| 862 | init_timer(&dd->ipath_stats_timer); | ||
| 863 | dd->ipath_stats_timer.function = ipath_get_faststats; | ||
| 864 | dd->ipath_stats_timer.data = (unsigned long) dd; | ||
| 865 | /* every 5 seconds; */ | ||
| 866 | dd->ipath_stats_timer.expires = jiffies + 5 * HZ; | ||
| 867 | /* takes ~16 seconds to overflow at full IB 4x bandwdith */ | ||
| 868 | add_timer(&dd->ipath_stats_timer); | ||
| 869 | dd->ipath_stats_timer_active = 1; | ||
| 870 | } | ||
| 871 | |||
| 872 | done: | ||
| 873 | if (!ret) { | ||
| 874 | ipath_get_guid(dd); | ||
| 875 | *dd->ipath_statusp |= IPATH_STATUS_CHIP_PRESENT; | ||
| 876 | if (!dd->ipath_f_intrsetup(dd)) { | ||
| 877 | /* now we can enable all interrupts from the chip */ | ||
| 878 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, | ||
| 879 | -1LL); | ||
| 880 | /* force re-interrupt of any pending interrupts. */ | ||
| 881 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, | ||
| 882 | 0ULL); | ||
| 883 | /* chip is usable; mark it as initialized */ | ||
| 884 | *dd->ipath_statusp |= IPATH_STATUS_INITTED; | ||
| 885 | } else | ||
| 886 | ipath_dev_err(dd, "No interrupts enabled, couldn't " | ||
| 887 | "setup interrupt address\n"); | ||
| 888 | |||
| 889 | if (dd->ipath_cfgports > ipath_stats.sps_nports) | ||
| 890 | /* | ||
| 891 | * sps_nports is a global, so, we set it to | ||
| 892 | * the highest number of ports of any of the | ||
| 893 | * chips we find; we never decrement it, at | ||
| 894 | * least for now. Since this might have changed | ||
| 895 | * over disable/enable or prior to reset, always | ||
| 896 | * do the check and potentially adjust. | ||
| 897 | */ | ||
| 898 | ipath_stats.sps_nports = dd->ipath_cfgports; | ||
| 899 | } else | ||
| 900 | ipath_dbg("Failed (%d) to initialize chip\n", ret); | ||
| 901 | |||
| 902 | /* if ret is non-zero, we probably should do some cleanup | ||
| 903 | here... */ | ||
| 904 | return ret; | ||
| 905 | } | ||
| 906 | |||
| 907 | static int ipath_set_kpiobufs(const char *str, struct kernel_param *kp) | ||
| 908 | { | ||
| 909 | struct ipath_devdata *dd; | ||
| 910 | unsigned long flags; | ||
| 911 | unsigned short val; | ||
| 912 | int ret; | ||
| 913 | |||
| 914 | ret = ipath_parse_ushort(str, &val); | ||
| 915 | |||
| 916 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 917 | |||
| 918 | if (ret < 0) | ||
| 919 | goto bail; | ||
| 920 | |||
| 921 | if (val == 0) { | ||
| 922 | ret = -EINVAL; | ||
| 923 | goto bail; | ||
| 924 | } | ||
| 925 | |||
| 926 | list_for_each_entry(dd, &ipath_dev_list, ipath_list) { | ||
| 927 | if (dd->ipath_kregbase) | ||
| 928 | continue; | ||
| 929 | if (val > (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
| 930 | (dd->ipath_cfgports * | ||
| 931 | IPATH_MIN_USER_PORT_BUFCNT))) | ||
| 932 | { | ||
| 933 | ipath_dev_err( | ||
| 934 | dd, | ||
| 935 | "Allocating %d PIO bufs for kernel leaves " | ||
| 936 | "too few for %d user ports (%d each)\n", | ||
| 937 | val, dd->ipath_cfgports - 1, | ||
| 938 | IPATH_MIN_USER_PORT_BUFCNT); | ||
| 939 | ret = -EINVAL; | ||
| 940 | goto bail; | ||
| 941 | } | ||
| 942 | dd->ipath_lastport_piobuf = | ||
| 943 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - val; | ||
| 944 | } | ||
| 945 | |||
| 946 | ret = 0; | ||
| 947 | bail: | ||
| 948 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 949 | |||
| 950 | return ret; | ||
| 951 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c new file mode 100644 index 000000000000..60f5f4108069 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
| @@ -0,0 +1,841 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/pci.h> | ||
| 34 | |||
| 35 | #include "ipath_kernel.h" | ||
| 36 | #include "ips_common.h" | ||
| 37 | #include "ipath_layer.h" | ||
| 38 | |||
| 39 | #define E_SUM_PKTERRS \ | ||
| 40 | (INFINIPATH_E_RHDRLEN | INFINIPATH_E_RBADTID | \ | ||
| 41 | INFINIPATH_E_RBADVERSION | INFINIPATH_E_RHDR | \ | ||
| 42 | INFINIPATH_E_RLONGPKTLEN | INFINIPATH_E_RSHORTPKTLEN | \ | ||
| 43 | INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RMINPKTLEN | \ | ||
| 44 | INFINIPATH_E_RFORMATERR | INFINIPATH_E_RUNSUPVL | \ | ||
| 45 | INFINIPATH_E_RUNEXPCHAR | INFINIPATH_E_REBP) | ||
| 46 | |||
| 47 | #define E_SUM_ERRS \ | ||
| 48 | (INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | \ | ||
| 49 | INFINIPATH_E_SDROPPEDDATAPKT | INFINIPATH_E_SDROPPEDSMPPKT | \ | ||
| 50 | INFINIPATH_E_SMAXPKTLEN | INFINIPATH_E_SUNSUPVL | \ | ||
| 51 | INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SPKTLEN | \ | ||
| 52 | INFINIPATH_E_INVALIDADDR) | ||
| 53 | |||
| 54 | static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs) | ||
| 55 | { | ||
| 56 | unsigned long sbuf[4]; | ||
| 57 | u64 ignore_this_time = 0; | ||
| 58 | u32 piobcnt; | ||
| 59 | |||
| 60 | /* if possible that sendbuffererror could be valid */ | ||
| 61 | piobcnt = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; | ||
| 62 | /* read these before writing errorclear */ | ||
| 63 | sbuf[0] = ipath_read_kreg64( | ||
| 64 | dd, dd->ipath_kregs->kr_sendbuffererror); | ||
| 65 | sbuf[1] = ipath_read_kreg64( | ||
| 66 | dd, dd->ipath_kregs->kr_sendbuffererror + 1); | ||
| 67 | if (piobcnt > 128) { | ||
| 68 | sbuf[2] = ipath_read_kreg64( | ||
| 69 | dd, dd->ipath_kregs->kr_sendbuffererror + 2); | ||
| 70 | sbuf[3] = ipath_read_kreg64( | ||
| 71 | dd, dd->ipath_kregs->kr_sendbuffererror + 3); | ||
| 72 | } | ||
| 73 | |||
| 74 | if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) { | ||
| 75 | int i; | ||
| 76 | |||
| 77 | ipath_cdbg(PKT, "SendbufErrs %lx %lx ", sbuf[0], sbuf[1]); | ||
| 78 | if (ipath_debug & __IPATH_PKTDBG && piobcnt > 128) | ||
| 79 | printk("%lx %lx ", sbuf[2], sbuf[3]); | ||
| 80 | for (i = 0; i < piobcnt; i++) { | ||
| 81 | if (test_bit(i, sbuf)) { | ||
| 82 | u32 __iomem *piobuf; | ||
| 83 | if (i < dd->ipath_piobcnt2k) | ||
| 84 | piobuf = (u32 __iomem *) | ||
| 85 | (dd->ipath_pio2kbase + | ||
| 86 | i * dd->ipath_palign); | ||
| 87 | else | ||
| 88 | piobuf = (u32 __iomem *) | ||
| 89 | (dd->ipath_pio4kbase + | ||
| 90 | (i - dd->ipath_piobcnt2k) * | ||
| 91 | dd->ipath_4kalign); | ||
| 92 | |||
| 93 | ipath_cdbg(PKT, | ||
| 94 | "PIObuf[%u] @%p pbc is %x; ", | ||
| 95 | i, piobuf, readl(piobuf)); | ||
| 96 | |||
| 97 | ipath_disarm_piobufs(dd, i, 1); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | if (ipath_debug & __IPATH_PKTDBG) | ||
| 101 | printk("\n"); | ||
| 102 | } | ||
| 103 | if ((errs & (INFINIPATH_E_SDROPPEDDATAPKT | | ||
| 104 | INFINIPATH_E_SDROPPEDSMPPKT | | ||
| 105 | INFINIPATH_E_SMINPKTLEN)) && | ||
| 106 | !(dd->ipath_flags & IPATH_LINKACTIVE)) { | ||
| 107 | /* | ||
| 108 | * This can happen when SMA is trying to bring the link | ||
| 109 | * up, but the IB link changes state at the "wrong" time. | ||
| 110 | * The IB logic then complains that the packet isn't | ||
| 111 | * valid. We don't want to confuse people, so we just | ||
| 112 | * don't print them, except at debug | ||
| 113 | */ | ||
| 114 | ipath_dbg("Ignoring pktsend errors %llx, because not " | ||
| 115 | "yet active\n", (unsigned long long) errs); | ||
| 116 | ignore_this_time = INFINIPATH_E_SDROPPEDDATAPKT | | ||
| 117 | INFINIPATH_E_SDROPPEDSMPPKT | | ||
| 118 | INFINIPATH_E_SMINPKTLEN; | ||
| 119 | } | ||
| 120 | |||
| 121 | return ignore_this_time; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* return the strings for the most common link states */ | ||
| 125 | static char *ib_linkstate(u32 linkstate) | ||
| 126 | { | ||
| 127 | char *ret; | ||
| 128 | |||
| 129 | switch (linkstate) { | ||
| 130 | case IPATH_IBSTATE_INIT: | ||
| 131 | ret = "Init"; | ||
| 132 | break; | ||
| 133 | case IPATH_IBSTATE_ARM: | ||
| 134 | ret = "Arm"; | ||
| 135 | break; | ||
| 136 | case IPATH_IBSTATE_ACTIVE: | ||
| 137 | ret = "Active"; | ||
| 138 | break; | ||
| 139 | default: | ||
| 140 | ret = "Down"; | ||
| 141 | } | ||
| 142 | |||
| 143 | return ret; | ||
| 144 | } | ||
| 145 | |||
| 146 | static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | ||
| 147 | ipath_err_t errs, int noprint) | ||
| 148 | { | ||
| 149 | u64 val; | ||
| 150 | u32 ltstate, lstate; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * even if diags are enabled, we want to notice LINKINIT, etc. | ||
| 154 | * We just don't want to change the LED state, or | ||
| 155 | * dd->ipath_kregs->kr_ibcctrl | ||
| 156 | */ | ||
| 157 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); | ||
| 158 | lstate = val & IPATH_IBSTATE_MASK; | ||
| 159 | if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || | ||
| 160 | lstate == IPATH_IBSTATE_ACTIVE) { | ||
| 161 | /* | ||
| 162 | * only print at SMA if there is a change, debug if not | ||
| 163 | * (sometimes we want to know that, usually not). | ||
| 164 | */ | ||
| 165 | if (lstate == ((unsigned) dd->ipath_lastibcstat | ||
| 166 | & IPATH_IBSTATE_MASK)) { | ||
| 167 | ipath_dbg("Status change intr but no change (%s)\n", | ||
| 168 | ib_linkstate(lstate)); | ||
| 169 | } | ||
| 170 | else | ||
| 171 | ipath_cdbg(SMA, "Unit %u link state %s, last " | ||
| 172 | "was %s\n", dd->ipath_unit, | ||
| 173 | ib_linkstate(lstate), | ||
| 174 | ib_linkstate((unsigned) | ||
| 175 | dd->ipath_lastibcstat | ||
| 176 | & IPATH_IBSTATE_MASK)); | ||
| 177 | } | ||
| 178 | else { | ||
| 179 | lstate = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK; | ||
| 180 | if (lstate == IPATH_IBSTATE_INIT || | ||
| 181 | lstate == IPATH_IBSTATE_ARM || | ||
| 182 | lstate == IPATH_IBSTATE_ACTIVE) | ||
| 183 | ipath_cdbg(SMA, "Unit %u link state down" | ||
| 184 | " (state 0x%x), from %s\n", | ||
| 185 | dd->ipath_unit, | ||
| 186 | (u32)val & IPATH_IBSTATE_MASK, | ||
| 187 | ib_linkstate(lstate)); | ||
| 188 | else | ||
| 189 | ipath_cdbg(VERBOSE, "Unit %u link state changed " | ||
| 190 | "to 0x%x from down (%x)\n", | ||
| 191 | dd->ipath_unit, (u32) val, lstate); | ||
| 192 | } | ||
| 193 | ltstate = (val >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & | ||
| 194 | INFINIPATH_IBCS_LINKTRAININGSTATE_MASK; | ||
| 195 | lstate = (val >> INFINIPATH_IBCS_LINKSTATE_SHIFT) & | ||
| 196 | INFINIPATH_IBCS_LINKSTATE_MASK; | ||
| 197 | |||
| 198 | if (ltstate == INFINIPATH_IBCS_LT_STATE_POLLACTIVE || | ||
| 199 | ltstate == INFINIPATH_IBCS_LT_STATE_POLLQUIET) { | ||
| 200 | u32 last_ltstate; | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Ignore cycling back and forth from Polling.Active | ||
| 204 | * to Polling.Quiet while waiting for the other end of | ||
| 205 | * the link to come up. We will cycle back and forth | ||
| 206 | * between them if no cable is plugged in, | ||
| 207 | * the other device is powered off or disabled, etc. | ||
| 208 | */ | ||
| 209 | last_ltstate = (dd->ipath_lastibcstat >> | ||
| 210 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | ||
| 211 | & INFINIPATH_IBCS_LINKTRAININGSTATE_MASK; | ||
| 212 | if (last_ltstate == INFINIPATH_IBCS_LT_STATE_POLLACTIVE | ||
| 213 | || last_ltstate == | ||
| 214 | INFINIPATH_IBCS_LT_STATE_POLLQUIET) { | ||
| 215 | if (dd->ipath_ibpollcnt > 40) { | ||
| 216 | dd->ipath_flags |= IPATH_NOCABLE; | ||
| 217 | *dd->ipath_statusp |= | ||
| 218 | IPATH_STATUS_IB_NOCABLE; | ||
| 219 | } else | ||
| 220 | dd->ipath_ibpollcnt++; | ||
| 221 | goto skip_ibchange; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | dd->ipath_ibpollcnt = 0; /* some state other than 2 or 3 */ | ||
| 225 | ipath_stats.sps_iblink++; | ||
| 226 | if (ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) { | ||
| 227 | dd->ipath_flags |= IPATH_LINKDOWN; | ||
| 228 | dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT | ||
| 229 | | IPATH_LINKACTIVE | | ||
| 230 | IPATH_LINKARMED); | ||
| 231 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; | ||
| 232 | if (!noprint) { | ||
| 233 | if (((dd->ipath_lastibcstat >> | ||
| 234 | INFINIPATH_IBCS_LINKSTATE_SHIFT) & | ||
| 235 | INFINIPATH_IBCS_LINKSTATE_MASK) | ||
| 236 | == INFINIPATH_IBCS_L_STATE_ACTIVE) | ||
| 237 | /* if from up to down be more vocal */ | ||
| 238 | ipath_cdbg(SMA, | ||
| 239 | "Unit %u link now down (%s)\n", | ||
| 240 | dd->ipath_unit, | ||
| 241 | ipath_ibcstatus_str[ltstate]); | ||
| 242 | else | ||
| 243 | ipath_cdbg(VERBOSE, "Unit %u link is " | ||
| 244 | "down (%s)\n", dd->ipath_unit, | ||
| 245 | ipath_ibcstatus_str[ltstate]); | ||
| 246 | } | ||
| 247 | |||
| 248 | dd->ipath_f_setextled(dd, lstate, ltstate); | ||
| 249 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_ACTIVE) { | ||
| 250 | dd->ipath_flags |= IPATH_LINKACTIVE; | ||
| 251 | dd->ipath_flags &= | ||
| 252 | ~(IPATH_LINKUNK | IPATH_LINKINIT | IPATH_LINKDOWN | | ||
| 253 | IPATH_LINKARMED | IPATH_NOCABLE); | ||
| 254 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_NOCABLE; | ||
| 255 | *dd->ipath_statusp |= | ||
| 256 | IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF; | ||
| 257 | dd->ipath_f_setextled(dd, lstate, ltstate); | ||
| 258 | |||
| 259 | __ipath_layer_intr(dd, IPATH_LAYER_INT_IF_UP); | ||
| 260 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) { | ||
| 261 | /* | ||
| 262 | * set INIT and DOWN. Down is checked by most of the other | ||
| 263 | * code, but INIT is useful to know in a few places. | ||
| 264 | */ | ||
| 265 | dd->ipath_flags |= IPATH_LINKINIT | IPATH_LINKDOWN; | ||
| 266 | dd->ipath_flags &= | ||
| 267 | ~(IPATH_LINKUNK | IPATH_LINKACTIVE | IPATH_LINKARMED | ||
| 268 | | IPATH_NOCABLE); | ||
| 269 | *dd->ipath_statusp &= ~(IPATH_STATUS_IB_NOCABLE | ||
| 270 | | IPATH_STATUS_IB_READY); | ||
| 271 | dd->ipath_f_setextled(dd, lstate, ltstate); | ||
| 272 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_ARM) { | ||
| 273 | dd->ipath_flags |= IPATH_LINKARMED; | ||
| 274 | dd->ipath_flags &= | ||
| 275 | ~(IPATH_LINKUNK | IPATH_LINKDOWN | IPATH_LINKINIT | | ||
| 276 | IPATH_LINKACTIVE | IPATH_NOCABLE); | ||
| 277 | *dd->ipath_statusp &= ~(IPATH_STATUS_IB_NOCABLE | ||
| 278 | | IPATH_STATUS_IB_READY); | ||
| 279 | dd->ipath_f_setextled(dd, lstate, ltstate); | ||
| 280 | } else { | ||
| 281 | if (!noprint) | ||
| 282 | ipath_dbg("IBstatuschange unit %u: %s (%x)\n", | ||
| 283 | dd->ipath_unit, | ||
| 284 | ipath_ibcstatus_str[ltstate], ltstate); | ||
| 285 | } | ||
| 286 | skip_ibchange: | ||
| 287 | dd->ipath_lastibcstat = val; | ||
| 288 | } | ||
| 289 | |||
| 290 | static void handle_supp_msgs(struct ipath_devdata *dd, | ||
| 291 | unsigned supp_msgs, char msg[512]) | ||
| 292 | { | ||
| 293 | /* | ||
| 294 | * Print the message unless it's ibc status change only, which | ||
| 295 | * happens so often we never want to count it. | ||
| 296 | */ | ||
| 297 | if (dd->ipath_lasterror & ~INFINIPATH_E_IBSTATUSCHANGED) { | ||
| 298 | ipath_decode_err(msg, sizeof msg, dd->ipath_lasterror & | ||
| 299 | ~INFINIPATH_E_IBSTATUSCHANGED); | ||
| 300 | if (dd->ipath_lasterror & | ||
| 301 | ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL)) | ||
| 302 | ipath_dev_err(dd, "Suppressed %u messages for " | ||
| 303 | "fast-repeating errors (%s) (%llx)\n", | ||
| 304 | supp_msgs, msg, | ||
| 305 | (unsigned long long) | ||
| 306 | dd->ipath_lasterror); | ||
| 307 | else { | ||
| 308 | /* | ||
| 309 | * rcvegrfull and rcvhdrqfull are "normal", for some | ||
| 310 | * types of processes (mostly benchmarks) that send | ||
| 311 | * huge numbers of messages, while not processing | ||
| 312 | * them. So only complain about these at debug | ||
| 313 | * level. | ||
| 314 | */ | ||
| 315 | ipath_dbg("Suppressed %u messages for %s\n", | ||
| 316 | supp_msgs, msg); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | static unsigned handle_frequent_errors(struct ipath_devdata *dd, | ||
| 322 | ipath_err_t errs, char msg[512], | ||
| 323 | int *noprint) | ||
| 324 | { | ||
| 325 | unsigned long nc; | ||
| 326 | static unsigned long nextmsg_time; | ||
| 327 | static unsigned nmsgs, supp_msgs; | ||
| 328 | |||
| 329 | /* | ||
| 330 | * Throttle back "fast" messages to no more than 10 per 5 seconds. | ||
| 331 | * This isn't perfect, but it's a reasonable heuristic. If we get | ||
| 332 | * more than 10, give a 6x longer delay. | ||
| 333 | */ | ||
| 334 | nc = jiffies; | ||
| 335 | if (nmsgs > 10) { | ||
| 336 | if (time_before(nc, nextmsg_time)) { | ||
| 337 | *noprint = 1; | ||
| 338 | if (!supp_msgs++) | ||
| 339 | nextmsg_time = nc + HZ * 3; | ||
| 340 | } | ||
| 341 | else if (supp_msgs) { | ||
| 342 | handle_supp_msgs(dd, supp_msgs, msg); | ||
| 343 | supp_msgs = 0; | ||
| 344 | nmsgs = 0; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | else if (!nmsgs++ || time_after(nc, nextmsg_time)) | ||
| 348 | nextmsg_time = nc + HZ / 2; | ||
| 349 | |||
| 350 | return supp_msgs; | ||
| 351 | } | ||
| 352 | |||
| 353 | static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | ||
| 354 | { | ||
| 355 | char msg[512]; | ||
| 356 | u64 ignore_this_time = 0; | ||
| 357 | int i; | ||
| 358 | int chkerrpkts = 0, noprint = 0; | ||
| 359 | unsigned supp_msgs; | ||
| 360 | |||
| 361 | supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint); | ||
| 362 | |||
| 363 | /* | ||
| 364 | * don't report errors that are masked (includes those always | ||
| 365 | * ignored) | ||
| 366 | */ | ||
| 367 | errs &= ~dd->ipath_maskederrs; | ||
| 368 | |||
| 369 | /* do these first, they are most important */ | ||
| 370 | if (errs & INFINIPATH_E_HARDWARE) { | ||
| 371 | /* reuse same msg buf */ | ||
| 372 | dd->ipath_f_handle_hwerrors(dd, msg, sizeof msg); | ||
| 373 | } | ||
| 374 | |||
| 375 | if (!noprint && (errs & ~infinipath_e_bitsextant)) | ||
| 376 | ipath_dev_err(dd, "error interrupt with unknown errors " | ||
| 377 | "%llx set\n", (unsigned long long) | ||
| 378 | (errs & ~infinipath_e_bitsextant)); | ||
| 379 | |||
| 380 | if (errs & E_SUM_ERRS) | ||
| 381 | ignore_this_time = handle_e_sum_errs(dd, errs); | ||
| 382 | |||
| 383 | if (supp_msgs == 250000) { | ||
| 384 | /* | ||
| 385 | * It's not entirely reasonable assuming that the errors set | ||
| 386 | * in the last clear period are all responsible for the | ||
| 387 | * problem, but the alternative is to assume it's the only | ||
| 388 | * ones on this particular interrupt, which also isn't great | ||
| 389 | */ | ||
| 390 | dd->ipath_maskederrs |= dd->ipath_lasterror | errs; | ||
| 391 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
| 392 | ~dd->ipath_maskederrs); | ||
| 393 | ipath_decode_err(msg, sizeof msg, | ||
| 394 | (dd->ipath_maskederrs & ~dd-> | ||
| 395 | ipath_ignorederrs)); | ||
| 396 | |||
| 397 | if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & | ||
| 398 | ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL)) | ||
| 399 | ipath_dev_err(dd, "Disabling error(s) %llx because " | ||
| 400 | "occuring too frequently (%s)\n", | ||
| 401 | (unsigned long long) | ||
| 402 | (dd->ipath_maskederrs & | ||
| 403 | ~dd->ipath_ignorederrs), msg); | ||
| 404 | else { | ||
| 405 | /* | ||
| 406 | * rcvegrfull and rcvhdrqfull are "normal", | ||
| 407 | * for some types of processes (mostly benchmarks) | ||
| 408 | * that send huge numbers of messages, while not | ||
| 409 | * processing them. So only complain about | ||
| 410 | * these at debug level. | ||
| 411 | */ | ||
| 412 | ipath_dbg("Disabling frequent queue full errors " | ||
| 413 | "(%s)\n", msg); | ||
| 414 | } | ||
| 415 | |||
| 416 | /* | ||
| 417 | * Re-enable the masked errors after around 3 minutes. in | ||
| 418 | * ipath_get_faststats(). If we have a series of fast | ||
| 419 | * repeating but different errors, the interval will keep | ||
| 420 | * stretching out, but that's OK, as that's pretty | ||
| 421 | * catastrophic. | ||
| 422 | */ | ||
| 423 | dd->ipath_unmasktime = jiffies + HZ * 180; | ||
| 424 | } | ||
| 425 | |||
| 426 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, errs); | ||
| 427 | if (ignore_this_time) | ||
| 428 | errs &= ~ignore_this_time; | ||
| 429 | if (errs & ~dd->ipath_lasterror) { | ||
| 430 | errs &= ~dd->ipath_lasterror; | ||
| 431 | /* never suppress duplicate hwerrors or ibstatuschange */ | ||
| 432 | dd->ipath_lasterror |= errs & | ||
| 433 | ~(INFINIPATH_E_HARDWARE | | ||
| 434 | INFINIPATH_E_IBSTATUSCHANGED); | ||
| 435 | } | ||
| 436 | if (!errs) | ||
| 437 | return; | ||
| 438 | |||
| 439 | if (!noprint) | ||
| 440 | /* | ||
| 441 | * the ones we mask off are handled specially below or above | ||
| 442 | */ | ||
| 443 | ipath_decode_err(msg, sizeof msg, | ||
| 444 | errs & ~(INFINIPATH_E_IBSTATUSCHANGED | | ||
| 445 | INFINIPATH_E_RRCVEGRFULL | | ||
| 446 | INFINIPATH_E_RRCVHDRFULL | | ||
| 447 | INFINIPATH_E_HARDWARE)); | ||
| 448 | else | ||
| 449 | /* so we don't need if (!noprint) at strlcat's below */ | ||
| 450 | *msg = 0; | ||
| 451 | |||
| 452 | if (errs & E_SUM_PKTERRS) { | ||
| 453 | ipath_stats.sps_pkterrs++; | ||
| 454 | chkerrpkts = 1; | ||
| 455 | } | ||
| 456 | if (errs & E_SUM_ERRS) | ||
| 457 | ipath_stats.sps_errs++; | ||
| 458 | |||
| 459 | if (errs & (INFINIPATH_E_RICRC | INFINIPATH_E_RVCRC)) { | ||
| 460 | ipath_stats.sps_crcerrs++; | ||
| 461 | chkerrpkts = 1; | ||
| 462 | } | ||
| 463 | |||
| 464 | /* | ||
| 465 | * We don't want to print these two as they happen, or we can make | ||
| 466 | * the situation even worse, because it takes so long to print | ||
| 467 | * messages to serial consoles. Kernel ports get printed from | ||
| 468 | * fast_stats, no more than every 5 seconds, user ports get printed | ||
| 469 | * on close | ||
| 470 | */ | ||
| 471 | if (errs & INFINIPATH_E_RRCVHDRFULL) { | ||
| 472 | int any; | ||
| 473 | u32 hd, tl; | ||
| 474 | ipath_stats.sps_hdrqfull++; | ||
| 475 | for (any = i = 0; i < dd->ipath_cfgports; i++) { | ||
| 476 | struct ipath_portdata *pd = dd->ipath_pd[i]; | ||
| 477 | if (i == 0) { | ||
| 478 | hd = dd->ipath_port0head; | ||
| 479 | tl = (u32) le64_to_cpu( | ||
| 480 | *dd->ipath_hdrqtailptr); | ||
| 481 | } else if (pd && pd->port_cnt && | ||
| 482 | pd->port_rcvhdrtail_kvaddr) { | ||
| 483 | /* | ||
| 484 | * don't report same point multiple times, | ||
| 485 | * except kernel | ||
| 486 | */ | ||
| 487 | tl = (u32) * pd->port_rcvhdrtail_kvaddr; | ||
| 488 | if (tl == dd->ipath_lastrcvhdrqtails[i]) | ||
| 489 | continue; | ||
| 490 | hd = ipath_read_ureg32(dd, ur_rcvhdrhead, | ||
| 491 | i); | ||
| 492 | } else | ||
| 493 | continue; | ||
| 494 | if (hd == (tl + 1) || | ||
| 495 | (!hd && tl == dd->ipath_hdrqlast)) { | ||
| 496 | dd->ipath_lastrcvhdrqtails[i] = tl; | ||
| 497 | pd->port_hdrqfull++; | ||
| 498 | if (i == 0) | ||
| 499 | chkerrpkts = 1; | ||
| 500 | } | ||
| 501 | } | ||
| 502 | } | ||
| 503 | if (errs & INFINIPATH_E_RRCVEGRFULL) { | ||
| 504 | /* | ||
| 505 | * since this is of less importance and not likely to | ||
| 506 | * happen without also getting hdrfull, only count | ||
| 507 | * occurrences; don't check each port (or even the kernel | ||
| 508 | * vs user) | ||
| 509 | */ | ||
| 510 | ipath_stats.sps_etidfull++; | ||
| 511 | if (dd->ipath_port0head != | ||
| 512 | (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) | ||
| 513 | chkerrpkts = 1; | ||
| 514 | } | ||
| 515 | |||
| 516 | /* | ||
| 517 | * do this before IBSTATUSCHANGED, in case both bits set in a single | ||
| 518 | * interrupt; we want the STATUSCHANGE to "win", so we do our | ||
| 519 | * internal copy of state machine correctly | ||
| 520 | */ | ||
| 521 | if (errs & INFINIPATH_E_RIBLOSTLINK) { | ||
| 522 | /* | ||
| 523 | * force through block below | ||
| 524 | */ | ||
| 525 | errs |= INFINIPATH_E_IBSTATUSCHANGED; | ||
| 526 | ipath_stats.sps_iblink++; | ||
| 527 | dd->ipath_flags |= IPATH_LINKDOWN; | ||
| 528 | dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT | ||
| 529 | | IPATH_LINKARMED | IPATH_LINKACTIVE); | ||
| 530 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; | ||
| 531 | if (!noprint) { | ||
| 532 | u64 st = ipath_read_kreg64( | ||
| 533 | dd, dd->ipath_kregs->kr_ibcstatus); | ||
| 534 | |||
| 535 | ipath_dbg("Lost link, link now down (%s)\n", | ||
| 536 | ipath_ibcstatus_str[st & 0xf]); | ||
| 537 | } | ||
| 538 | } | ||
| 539 | if (errs & INFINIPATH_E_IBSTATUSCHANGED) | ||
| 540 | handle_e_ibstatuschanged(dd, errs, noprint); | ||
| 541 | |||
| 542 | if (errs & INFINIPATH_E_RESET) { | ||
| 543 | if (!noprint) | ||
| 544 | ipath_dev_err(dd, "Got reset, requires re-init " | ||
| 545 | "(unload and reload driver)\n"); | ||
| 546 | dd->ipath_flags &= ~IPATH_INITTED; /* needs re-init */ | ||
| 547 | /* mark as having had error */ | ||
| 548 | *dd->ipath_statusp |= IPATH_STATUS_HWERROR; | ||
| 549 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_CONF; | ||
| 550 | } | ||
| 551 | |||
| 552 | if (!noprint && *msg) | ||
| 553 | ipath_dev_err(dd, "%s error\n", msg); | ||
| 554 | if (dd->ipath_sma_state_wanted & dd->ipath_flags) { | ||
| 555 | ipath_cdbg(VERBOSE, "sma wanted state %x, iflags now %x, " | ||
| 556 | "waking\n", dd->ipath_sma_state_wanted, | ||
| 557 | dd->ipath_flags); | ||
| 558 | wake_up_interruptible(&ipath_sma_state_wait); | ||
| 559 | } | ||
| 560 | |||
| 561 | if (chkerrpkts) | ||
| 562 | /* process possible error packets in hdrq */ | ||
| 563 | ipath_kreceive(dd); | ||
| 564 | } | ||
| 565 | |||
| 566 | /* this is separate to allow for better optimization of ipath_intr() */ | ||
| 567 | |||
| 568 | static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) | ||
| 569 | { | ||
| 570 | /* | ||
| 571 | * sometimes happen during driver init and unload, don't want | ||
| 572 | * to process any interrupts at that point | ||
| 573 | */ | ||
| 574 | |||
| 575 | /* this is just a bandaid, not a fix, if something goes badly | ||
| 576 | * wrong */ | ||
| 577 | if (++*unexpectp > 100) { | ||
| 578 | if (++*unexpectp > 105) { | ||
| 579 | /* | ||
| 580 | * ok, we must be taking somebody else's interrupts, | ||
| 581 | * due to a messed up mptable and/or PIRQ table, so | ||
| 582 | * unregister the interrupt. We've seen this during | ||
| 583 | * linuxbios development work, and it may happen in | ||
| 584 | * the future again. | ||
| 585 | */ | ||
| 586 | if (dd->pcidev && dd->pcidev->irq) { | ||
| 587 | ipath_dev_err(dd, "Now %u unexpected " | ||
| 588 | "interrupts, unregistering " | ||
| 589 | "interrupt handler\n", | ||
| 590 | *unexpectp); | ||
| 591 | ipath_dbg("free_irq of irq %x\n", | ||
| 592 | dd->pcidev->irq); | ||
| 593 | free_irq(dd->pcidev->irq, dd); | ||
| 594 | } | ||
| 595 | } | ||
| 596 | if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { | ||
| 597 | ipath_dev_err(dd, "%u unexpected interrupts, " | ||
| 598 | "disabling interrupts completely\n", | ||
| 599 | *unexpectp); | ||
| 600 | /* | ||
| 601 | * disable all interrupts, something is very wrong | ||
| 602 | */ | ||
| 603 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, | ||
| 604 | 0ULL); | ||
| 605 | } | ||
| 606 | } else if (*unexpectp > 1) | ||
| 607 | ipath_dbg("Interrupt when not ready, should not happen, " | ||
| 608 | "ignoring\n"); | ||
| 609 | } | ||
| 610 | |||
| 611 | static void ipath_bad_regread(struct ipath_devdata *dd) | ||
| 612 | { | ||
| 613 | static int allbits; | ||
| 614 | |||
| 615 | /* separate routine, for better optimization of ipath_intr() */ | ||
| 616 | |||
| 617 | /* | ||
| 618 | * We print the message and disable interrupts, in hope of | ||
| 619 | * having a better chance of debugging the problem. | ||
| 620 | */ | ||
| 621 | ipath_dev_err(dd, | ||
| 622 | "Read of interrupt status failed (all bits set)\n"); | ||
| 623 | if (allbits++) { | ||
| 624 | /* disable all interrupts, something is very wrong */ | ||
| 625 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); | ||
| 626 | if (allbits == 2) { | ||
| 627 | ipath_dev_err(dd, "Still bad interrupt status, " | ||
| 628 | "unregistering interrupt\n"); | ||
| 629 | free_irq(dd->pcidev->irq, dd); | ||
| 630 | } else if (allbits > 2) { | ||
| 631 | if ((allbits % 10000) == 0) | ||
| 632 | printk("."); | ||
| 633 | } else | ||
| 634 | ipath_dev_err(dd, "Disabling interrupts, " | ||
| 635 | "multiple errors\n"); | ||
| 636 | } | ||
| 637 | } | ||
| 638 | |||
| 639 | static void handle_port_pioavail(struct ipath_devdata *dd) | ||
| 640 | { | ||
| 641 | u32 i; | ||
| 642 | /* | ||
| 643 | * start from port 1, since for now port 0 is never using | ||
| 644 | * wait_event for PIO | ||
| 645 | */ | ||
| 646 | for (i = 1; dd->ipath_portpiowait && i < dd->ipath_cfgports; i++) { | ||
| 647 | struct ipath_portdata *pd = dd->ipath_pd[i]; | ||
| 648 | |||
| 649 | if (pd && pd->port_cnt && | ||
| 650 | dd->ipath_portpiowait & (1U << i)) { | ||
| 651 | clear_bit(i, &dd->ipath_portpiowait); | ||
| 652 | if (test_bit(IPATH_PORT_WAITING_PIO, | ||
| 653 | &pd->port_flag)) { | ||
| 654 | clear_bit(IPATH_PORT_WAITING_PIO, | ||
| 655 | &pd->port_flag); | ||
| 656 | wake_up_interruptible(&pd->port_wait); | ||
| 657 | } | ||
| 658 | } | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | static void handle_layer_pioavail(struct ipath_devdata *dd) | ||
| 663 | { | ||
| 664 | int ret; | ||
| 665 | |||
| 666 | ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE); | ||
| 667 | if (ret > 0) | ||
| 668 | goto clear; | ||
| 669 | |||
| 670 | ret = __ipath_verbs_piobufavail(dd); | ||
| 671 | if (ret > 0) | ||
| 672 | goto clear; | ||
| 673 | |||
| 674 | return; | ||
| 675 | clear: | ||
| 676 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | ||
| 677 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 678 | dd->ipath_sendctrl); | ||
| 679 | } | ||
| 680 | |||
| 681 | static void handle_rcv(struct ipath_devdata *dd, u32 istat) | ||
| 682 | { | ||
| 683 | u64 portr; | ||
| 684 | int i; | ||
| 685 | int rcvdint = 0; | ||
| 686 | |||
| 687 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & | ||
| 688 | infinipath_i_rcvavail_mask) | ||
| 689 | | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & | ||
| 690 | infinipath_i_rcvurg_mask); | ||
| 691 | for (i = 0; i < dd->ipath_cfgports; i++) { | ||
| 692 | struct ipath_portdata *pd = dd->ipath_pd[i]; | ||
| 693 | if (portr & (1 << i) && pd && | ||
| 694 | pd->port_cnt) { | ||
| 695 | if (i == 0) | ||
| 696 | ipath_kreceive(dd); | ||
| 697 | else if (test_bit(IPATH_PORT_WAITING_RCV, | ||
| 698 | &pd->port_flag)) { | ||
| 699 | int rcbit; | ||
| 700 | clear_bit(IPATH_PORT_WAITING_RCV, | ||
| 701 | &pd->port_flag); | ||
| 702 | rcbit = i + INFINIPATH_R_INTRAVAIL_SHIFT; | ||
| 703 | clear_bit(1UL << rcbit, &dd->ipath_rcvctrl); | ||
| 704 | wake_up_interruptible(&pd->port_wait); | ||
| 705 | rcvdint = 1; | ||
| 706 | } | ||
| 707 | } | ||
| 708 | } | ||
| 709 | if (rcvdint) { | ||
| 710 | /* only want to take one interrupt, so turn off the rcv | ||
| 711 | * interrupt for all the ports that we did the wakeup on | ||
| 712 | * (but never for kernel port) | ||
| 713 | */ | ||
| 714 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | ||
| 715 | dd->ipath_rcvctrl); | ||
| 716 | } | ||
| 717 | } | ||
| 718 | |||
| 719 | irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs) | ||
| 720 | { | ||
| 721 | struct ipath_devdata *dd = data; | ||
| 722 | u32 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); | ||
| 723 | ipath_err_t estat = 0; | ||
| 724 | static unsigned unexpected = 0; | ||
| 725 | irqreturn_t ret; | ||
| 726 | |||
| 727 | if (unlikely(!istat)) { | ||
| 728 | ipath_stats.sps_nullintr++; | ||
| 729 | ret = IRQ_NONE; /* not our interrupt, or already handled */ | ||
| 730 | goto bail; | ||
| 731 | } | ||
| 732 | if (unlikely(istat == -1)) { | ||
| 733 | ipath_bad_regread(dd); | ||
| 734 | /* don't know if it was our interrupt or not */ | ||
| 735 | ret = IRQ_NONE; | ||
| 736 | goto bail; | ||
| 737 | } | ||
| 738 | |||
| 739 | ipath_stats.sps_ints++; | ||
| 740 | |||
| 741 | /* | ||
| 742 | * this needs to be flags&initted, not statusp, so we keep | ||
| 743 | * taking interrupts even after link goes down, etc. | ||
| 744 | * Also, we *must* clear the interrupt at some point, or we won't | ||
| 745 | * take it again, which can be real bad for errors, etc... | ||
| 746 | */ | ||
| 747 | |||
| 748 | if (!(dd->ipath_flags & IPATH_INITTED)) { | ||
| 749 | ipath_bad_intr(dd, &unexpected); | ||
| 750 | ret = IRQ_NONE; | ||
| 751 | goto bail; | ||
| 752 | } | ||
| 753 | if (unexpected) | ||
| 754 | unexpected = 0; | ||
| 755 | |||
| 756 | ipath_cdbg(VERBOSE, "intr stat=0x%x\n", istat); | ||
| 757 | |||
| 758 | if (istat & ~infinipath_i_bitsextant) | ||
| 759 | ipath_dev_err(dd, | ||
| 760 | "interrupt with unknown interrupts %x set\n", | ||
| 761 | istat & (u32) ~ infinipath_i_bitsextant); | ||
| 762 | |||
| 763 | if (istat & INFINIPATH_I_ERROR) { | ||
| 764 | ipath_stats.sps_errints++; | ||
| 765 | estat = ipath_read_kreg64(dd, | ||
| 766 | dd->ipath_kregs->kr_errorstatus); | ||
| 767 | if (!estat) | ||
| 768 | dev_info(&dd->pcidev->dev, "error interrupt (%x), " | ||
| 769 | "but no error bits set!\n", istat); | ||
| 770 | else if (estat == -1LL) | ||
| 771 | /* | ||
| 772 | * should we try clearing all, or hope next read | ||
| 773 | * works? | ||
| 774 | */ | ||
| 775 | ipath_dev_err(dd, "Read of error status failed " | ||
| 776 | "(all bits set); ignoring\n"); | ||
| 777 | else | ||
| 778 | handle_errors(dd, estat); | ||
| 779 | } | ||
| 780 | |||
| 781 | if (istat & INFINIPATH_I_GPIO) { | ||
| 782 | if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) { | ||
| 783 | u32 gpiostatus; | ||
| 784 | gpiostatus = ipath_read_kreg32( | ||
| 785 | dd, dd->ipath_kregs->kr_gpio_status); | ||
| 786 | ipath_dbg("Unexpected GPIO interrupt bits %x\n", | ||
| 787 | gpiostatus); | ||
| 788 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, | ||
| 789 | gpiostatus); | ||
| 790 | } | ||
| 791 | else { | ||
| 792 | /* Clear GPIO status bit 2 */ | ||
| 793 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, | ||
| 794 | (u64) (1 << 2)); | ||
| 795 | |||
| 796 | /* | ||
| 797 | * Packets are available in the port 0 rcv queue. | ||
| 798 | * Eventually this needs to be generalized to check | ||
| 799 | * IPATH_GPIO_INTR, and the specific GPIO bit, if | ||
| 800 | * GPIO interrupts are used for anything else. | ||
| 801 | */ | ||
| 802 | ipath_kreceive(dd); | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | /* | ||
| 807 | * clear the ones we will deal with on this round | ||
| 808 | * We clear it early, mostly for receive interrupts, so we | ||
| 809 | * know the chip will have seen this by the time we process | ||
| 810 | * the queue, and will re-interrupt if necessary. The processor | ||
| 811 | * itself won't take the interrupt again until we return. | ||
| 812 | */ | ||
| 813 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); | ||
| 814 | |||
| 815 | if (istat & INFINIPATH_I_SPIOBUFAVAIL) { | ||
| 816 | clear_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | ||
| 817 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 818 | dd->ipath_sendctrl); | ||
| 819 | |||
| 820 | if (dd->ipath_portpiowait) | ||
| 821 | handle_port_pioavail(dd); | ||
| 822 | |||
| 823 | handle_layer_pioavail(dd); | ||
| 824 | } | ||
| 825 | |||
| 826 | /* | ||
| 827 | * we check for both transition from empty to non-empty, and urgent | ||
| 828 | * packets (those with the interrupt bit set in the header) | ||
| 829 | */ | ||
| 830 | |||
| 831 | if (istat & ((infinipath_i_rcvavail_mask << | ||
| 832 | INFINIPATH_I_RCVAVAIL_SHIFT) | ||
| 833 | | (infinipath_i_rcvurg_mask << | ||
| 834 | INFINIPATH_I_RCVURG_SHIFT))) | ||
| 835 | handle_rcv(dd, istat); | ||
| 836 | |||
| 837 | ret = IRQ_HANDLED; | ||
| 838 | |||
| 839 | bail: | ||
| 840 | return ret; | ||
| 841 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h new file mode 100644 index 000000000000..159d0aed31a5 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
| @@ -0,0 +1,884 @@ | |||
| 1 | #ifndef _IPATH_KERNEL_H | ||
| 2 | #define _IPATH_KERNEL_H | ||
| 3 | /* | ||
| 4 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * 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 | * General Public License (GPL) Version 2, available from the file | ||
| 9 | * COPYING in the main directory of this source tree, or the | ||
| 10 | * OpenIB.org BSD license below: | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or | ||
| 13 | * without modification, are permitted provided that the following | ||
| 14 | * conditions are met: | ||
| 15 | * | ||
| 16 | * - Redistributions of source code must retain the above | ||
| 17 | * copyright notice, this list of conditions and the following | ||
| 18 | * disclaimer. | ||
| 19 | * | ||
| 20 | * - Redistributions in binary form must reproduce the above | ||
| 21 | * copyright notice, this list of conditions and the following | ||
| 22 | * disclaimer in the documentation and/or other materials | ||
| 23 | * provided with the distribution. | ||
| 24 | * | ||
| 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 32 | * SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | /* | ||
| 36 | * This header file is the base header file for infinipath kernel code | ||
| 37 | * ipath_user.h serves a similar purpose for user code. | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include <linux/interrupt.h> | ||
| 41 | #include <asm/io.h> | ||
| 42 | |||
| 43 | #include "ipath_common.h" | ||
| 44 | #include "ipath_debug.h" | ||
| 45 | #include "ipath_registers.h" | ||
| 46 | |||
| 47 | /* only s/w major version of InfiniPath we can handle */ | ||
| 48 | #define IPATH_CHIP_VERS_MAJ 2U | ||
| 49 | |||
| 50 | /* don't care about this except printing */ | ||
| 51 | #define IPATH_CHIP_VERS_MIN 0U | ||
| 52 | |||
| 53 | /* temporary, maybe always */ | ||
| 54 | extern struct infinipath_stats ipath_stats; | ||
| 55 | |||
| 56 | #define IPATH_CHIP_SWVERSION IPATH_CHIP_VERS_MAJ | ||
| 57 | |||
| 58 | struct ipath_portdata { | ||
| 59 | void **port_rcvegrbuf; | ||
| 60 | dma_addr_t *port_rcvegrbuf_phys; | ||
| 61 | /* rcvhdrq base, needs mmap before useful */ | ||
| 62 | void *port_rcvhdrq; | ||
| 63 | /* kernel virtual address where hdrqtail is updated */ | ||
| 64 | u64 *port_rcvhdrtail_kvaddr; | ||
| 65 | /* page * used for uaddr */ | ||
| 66 | struct page *port_rcvhdrtail_pagep; | ||
| 67 | /* | ||
| 68 | * temp buffer for expected send setup, allocated at open, instead | ||
| 69 | * of each setup call | ||
| 70 | */ | ||
| 71 | void *port_tid_pg_list; | ||
| 72 | /* when waiting for rcv or pioavail */ | ||
| 73 | wait_queue_head_t port_wait; | ||
| 74 | /* | ||
| 75 | * rcvegr bufs base, physical, must fit | ||
| 76 | * in 44 bits so 32 bit programs mmap64 44 bit works) | ||
| 77 | */ | ||
| 78 | dma_addr_t port_rcvegr_phys; | ||
| 79 | /* mmap of hdrq, must fit in 44 bits */ | ||
| 80 | dma_addr_t port_rcvhdrq_phys; | ||
| 81 | /* | ||
| 82 | * the actual user address that we ipath_mlock'ed, so we can | ||
| 83 | * ipath_munlock it at close | ||
| 84 | */ | ||
| 85 | unsigned long port_rcvhdrtail_uaddr; | ||
| 86 | /* | ||
| 87 | * number of opens on this instance (0 or 1; ignoring forks, dup, | ||
| 88 | * etc. for now) | ||
| 89 | */ | ||
| 90 | int port_cnt; | ||
| 91 | /* | ||
| 92 | * how much space to leave at start of eager TID entries for | ||
| 93 | * protocol use, on each TID | ||
| 94 | */ | ||
| 95 | /* instead of calculating it */ | ||
| 96 | unsigned port_port; | ||
| 97 | /* chip offset of PIO buffers for this port */ | ||
| 98 | u32 port_piobufs; | ||
| 99 | /* how many alloc_pages() chunks in port_rcvegrbuf_pages */ | ||
| 100 | u32 port_rcvegrbuf_chunks; | ||
| 101 | /* how many egrbufs per chunk */ | ||
| 102 | u32 port_rcvegrbufs_perchunk; | ||
| 103 | /* order for port_rcvegrbuf_pages */ | ||
| 104 | size_t port_rcvegrbuf_size; | ||
| 105 | /* rcvhdrq size (for freeing) */ | ||
| 106 | size_t port_rcvhdrq_size; | ||
| 107 | /* next expected TID to check when looking for free */ | ||
| 108 | u32 port_tidcursor; | ||
| 109 | /* next expected TID to check */ | ||
| 110 | unsigned long port_flag; | ||
| 111 | /* WAIT_RCV that timed out, no interrupt */ | ||
| 112 | u32 port_rcvwait_to; | ||
| 113 | /* WAIT_PIO that timed out, no interrupt */ | ||
| 114 | u32 port_piowait_to; | ||
| 115 | /* WAIT_RCV already happened, no wait */ | ||
| 116 | u32 port_rcvnowait; | ||
| 117 | /* WAIT_PIO already happened, no wait */ | ||
| 118 | u32 port_pionowait; | ||
| 119 | /* total number of rcvhdrqfull errors */ | ||
| 120 | u32 port_hdrqfull; | ||
| 121 | /* pid of process using this port */ | ||
| 122 | pid_t port_pid; | ||
| 123 | /* same size as task_struct .comm[] */ | ||
| 124 | char port_comm[16]; | ||
| 125 | /* pkeys set by this use of this port */ | ||
| 126 | u16 port_pkeys[4]; | ||
| 127 | /* so file ops can get at unit */ | ||
| 128 | struct ipath_devdata *port_dd; | ||
| 129 | }; | ||
| 130 | |||
| 131 | struct sk_buff; | ||
| 132 | |||
| 133 | /* | ||
| 134 | * control information for layered drivers | ||
| 135 | */ | ||
| 136 | struct _ipath_layer { | ||
| 137 | void *l_arg; | ||
| 138 | }; | ||
| 139 | |||
| 140 | /* Verbs layer interface */ | ||
| 141 | struct _verbs_layer { | ||
| 142 | void *l_arg; | ||
| 143 | struct timer_list l_timer; | ||
| 144 | }; | ||
| 145 | |||
| 146 | struct ipath_devdata { | ||
| 147 | struct list_head ipath_list; | ||
| 148 | |||
| 149 | struct ipath_kregs const *ipath_kregs; | ||
| 150 | struct ipath_cregs const *ipath_cregs; | ||
| 151 | |||
| 152 | /* mem-mapped pointer to base of chip regs */ | ||
| 153 | u64 __iomem *ipath_kregbase; | ||
| 154 | /* end of mem-mapped chip space; range checking */ | ||
| 155 | u64 __iomem *ipath_kregend; | ||
| 156 | /* physical address of chip for io_remap, etc. */ | ||
| 157 | unsigned long ipath_physaddr; | ||
| 158 | /* base of memory alloced for ipath_kregbase, for free */ | ||
| 159 | u64 *ipath_kregalloc; | ||
| 160 | /* | ||
| 161 | * version of kregbase that doesn't have high bits set (for 32 bit | ||
| 162 | * programs, so mmap64 44 bit works) | ||
| 163 | */ | ||
| 164 | u64 __iomem *ipath_kregvirt; | ||
| 165 | /* | ||
| 166 | * virtual address where port0 rcvhdrqtail updated for this unit. | ||
| 167 | * only written to by the chip, not the driver. | ||
| 168 | */ | ||
| 169 | volatile __le64 *ipath_hdrqtailptr; | ||
| 170 | dma_addr_t ipath_dma_addr; | ||
| 171 | /* ipath_cfgports pointers */ | ||
| 172 | struct ipath_portdata **ipath_pd; | ||
| 173 | /* sk_buffs used by port 0 eager receive queue */ | ||
| 174 | struct sk_buff **ipath_port0_skbs; | ||
| 175 | /* kvirt address of 1st 2k pio buffer */ | ||
| 176 | void __iomem *ipath_pio2kbase; | ||
| 177 | /* kvirt address of 1st 4k pio buffer */ | ||
| 178 | void __iomem *ipath_pio4kbase; | ||
| 179 | /* | ||
| 180 | * points to area where PIOavail registers will be DMA'ed. | ||
| 181 | * Has to be on a page of it's own, because the page will be | ||
| 182 | * mapped into user program space. This copy is *ONLY* ever | ||
| 183 | * written by DMA, not by the driver! Need a copy per device | ||
| 184 | * when we get to multiple devices | ||
| 185 | */ | ||
| 186 | volatile __le64 *ipath_pioavailregs_dma; | ||
| 187 | /* physical address where updates occur */ | ||
| 188 | dma_addr_t ipath_pioavailregs_phys; | ||
| 189 | struct _ipath_layer ipath_layer; | ||
| 190 | /* setup intr */ | ||
| 191 | int (*ipath_f_intrsetup)(struct ipath_devdata *); | ||
| 192 | /* setup on-chip bus config */ | ||
| 193 | int (*ipath_f_bus)(struct ipath_devdata *, struct pci_dev *); | ||
| 194 | /* hard reset chip */ | ||
| 195 | int (*ipath_f_reset)(struct ipath_devdata *); | ||
| 196 | int (*ipath_f_get_boardname)(struct ipath_devdata *, char *, | ||
| 197 | size_t); | ||
| 198 | void (*ipath_f_init_hwerrors)(struct ipath_devdata *); | ||
| 199 | void (*ipath_f_handle_hwerrors)(struct ipath_devdata *, char *, | ||
| 200 | size_t); | ||
| 201 | void (*ipath_f_quiet_serdes)(struct ipath_devdata *); | ||
| 202 | int (*ipath_f_bringup_serdes)(struct ipath_devdata *); | ||
| 203 | int (*ipath_f_early_init)(struct ipath_devdata *); | ||
| 204 | void (*ipath_f_clear_tids)(struct ipath_devdata *, unsigned); | ||
| 205 | void (*ipath_f_put_tid)(struct ipath_devdata *, u64 __iomem*, | ||
| 206 | u32, unsigned long); | ||
| 207 | void (*ipath_f_tidtemplate)(struct ipath_devdata *); | ||
| 208 | void (*ipath_f_cleanup)(struct ipath_devdata *); | ||
| 209 | void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); | ||
| 210 | /* fill out chip-specific fields */ | ||
| 211 | int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); | ||
| 212 | struct _verbs_layer verbs_layer; | ||
| 213 | /* total dwords sent (summed from counter) */ | ||
| 214 | u64 ipath_sword; | ||
| 215 | /* total dwords rcvd (summed from counter) */ | ||
| 216 | u64 ipath_rword; | ||
| 217 | /* total packets sent (summed from counter) */ | ||
| 218 | u64 ipath_spkts; | ||
| 219 | /* total packets rcvd (summed from counter) */ | ||
| 220 | u64 ipath_rpkts; | ||
| 221 | /* ipath_statusp initially points to this. */ | ||
| 222 | u64 _ipath_status; | ||
| 223 | /* GUID for this interface, in network order */ | ||
| 224 | __be64 ipath_guid; | ||
| 225 | /* | ||
| 226 | * aggregrate of error bits reported since last cleared, for | ||
| 227 | * limiting of error reporting | ||
| 228 | */ | ||
| 229 | ipath_err_t ipath_lasterror; | ||
| 230 | /* | ||
| 231 | * aggregrate of error bits reported since last cleared, for | ||
| 232 | * limiting of hwerror reporting | ||
| 233 | */ | ||
| 234 | ipath_err_t ipath_lasthwerror; | ||
| 235 | /* | ||
| 236 | * errors masked because they occur too fast, also includes errors | ||
| 237 | * that are always ignored (ipath_ignorederrs) | ||
| 238 | */ | ||
| 239 | ipath_err_t ipath_maskederrs; | ||
| 240 | /* time in jiffies at which to re-enable maskederrs */ | ||
| 241 | unsigned long ipath_unmasktime; | ||
| 242 | /* | ||
| 243 | * errors always ignored (masked), at least for a given | ||
| 244 | * chip/device, because they are wrong or not useful | ||
| 245 | */ | ||
| 246 | ipath_err_t ipath_ignorederrs; | ||
| 247 | /* count of egrfull errors, combined for all ports */ | ||
| 248 | u64 ipath_last_tidfull; | ||
| 249 | /* for ipath_qcheck() */ | ||
| 250 | u64 ipath_lastport0rcv_cnt; | ||
| 251 | /* template for writing TIDs */ | ||
| 252 | u64 ipath_tidtemplate; | ||
| 253 | /* value to write to free TIDs */ | ||
| 254 | u64 ipath_tidinvalid; | ||
| 255 | /* PE-800 rcv interrupt setup */ | ||
| 256 | u64 ipath_rhdrhead_intr_off; | ||
| 257 | |||
| 258 | /* size of memory at ipath_kregbase */ | ||
| 259 | u32 ipath_kregsize; | ||
| 260 | /* number of registers used for pioavail */ | ||
| 261 | u32 ipath_pioavregs; | ||
| 262 | /* IPATH_POLL, etc. */ | ||
| 263 | u32 ipath_flags; | ||
| 264 | /* ipath_flags sma is waiting for */ | ||
| 265 | u32 ipath_sma_state_wanted; | ||
| 266 | /* last buffer for user use, first buf for kernel use is this | ||
| 267 | * index. */ | ||
| 268 | u32 ipath_lastport_piobuf; | ||
| 269 | /* is a stats timer active */ | ||
| 270 | u32 ipath_stats_timer_active; | ||
| 271 | /* dwords sent read from counter */ | ||
| 272 | u32 ipath_lastsword; | ||
| 273 | /* dwords received read from counter */ | ||
| 274 | u32 ipath_lastrword; | ||
| 275 | /* sent packets read from counter */ | ||
| 276 | u32 ipath_lastspkts; | ||
| 277 | /* received packets read from counter */ | ||
| 278 | u32 ipath_lastrpkts; | ||
| 279 | /* pio bufs allocated per port */ | ||
| 280 | u32 ipath_pbufsport; | ||
| 281 | /* | ||
| 282 | * number of ports configured as max; zero is set to number chip | ||
| 283 | * supports, less gives more pio bufs/port, etc. | ||
| 284 | */ | ||
| 285 | u32 ipath_cfgports; | ||
| 286 | /* port0 rcvhdrq head offset */ | ||
| 287 | u32 ipath_port0head; | ||
| 288 | /* count of port 0 hdrqfull errors */ | ||
| 289 | u32 ipath_p0_hdrqfull; | ||
| 290 | |||
| 291 | /* | ||
| 292 | * (*cfgports) used to suppress multiple instances of same | ||
| 293 | * port staying stuck at same point | ||
| 294 | */ | ||
| 295 | u32 *ipath_lastrcvhdrqtails; | ||
| 296 | /* | ||
| 297 | * (*cfgports) used to suppress multiple instances of same | ||
| 298 | * port staying stuck at same point | ||
| 299 | */ | ||
| 300 | u32 *ipath_lastegrheads; | ||
| 301 | /* | ||
| 302 | * index of last piobuffer we used. Speeds up searching, by | ||
| 303 | * starting at this point. Doesn't matter if multiple cpu's use and | ||
| 304 | * update, last updater is only write that matters. Whenever it | ||
| 305 | * wraps, we update shadow copies. Need a copy per device when we | ||
| 306 | * get to multiple devices | ||
| 307 | */ | ||
| 308 | u32 ipath_lastpioindex; | ||
| 309 | /* max length of freezemsg */ | ||
| 310 | u32 ipath_freezelen; | ||
| 311 | /* | ||
| 312 | * consecutive times we wanted a PIO buffer but were unable to | ||
| 313 | * get one | ||
| 314 | */ | ||
| 315 | u32 ipath_consec_nopiobuf; | ||
| 316 | /* | ||
| 317 | * hint that we should update ipath_pioavailshadow before | ||
| 318 | * looking for a PIO buffer | ||
| 319 | */ | ||
| 320 | u32 ipath_upd_pio_shadow; | ||
| 321 | /* so we can rewrite it after a chip reset */ | ||
| 322 | u32 ipath_pcibar0; | ||
| 323 | /* so we can rewrite it after a chip reset */ | ||
| 324 | u32 ipath_pcibar1; | ||
| 325 | /* sequential tries for SMA send and no bufs */ | ||
| 326 | u32 ipath_nosma_bufs; | ||
| 327 | /* duration (seconds) ipath_nosma_bufs set */ | ||
| 328 | u32 ipath_nosma_secs; | ||
| 329 | |||
| 330 | /* HT/PCI Vendor ID (here for NodeInfo) */ | ||
| 331 | u16 ipath_vendorid; | ||
| 332 | /* HT/PCI Device ID (here for NodeInfo) */ | ||
| 333 | u16 ipath_deviceid; | ||
| 334 | /* offset in HT config space of slave/primary interface block */ | ||
| 335 | u8 ipath_ht_slave_off; | ||
| 336 | /* for write combining settings */ | ||
| 337 | unsigned long ipath_wc_cookie; | ||
| 338 | /* ref count for each pkey */ | ||
| 339 | atomic_t ipath_pkeyrefs[4]; | ||
| 340 | /* shadow copy of all exptids physaddr; used only by funcsim */ | ||
| 341 | u64 *ipath_tidsimshadow; | ||
| 342 | /* shadow copy of struct page *'s for exp tid pages */ | ||
| 343 | struct page **ipath_pageshadow; | ||
| 344 | /* lock to workaround chip bug 9437 */ | ||
| 345 | spinlock_t ipath_tid_lock; | ||
| 346 | |||
| 347 | /* | ||
| 348 | * IPATH_STATUS_*, | ||
| 349 | * this address is mapped readonly into user processes so they can | ||
| 350 | * get status cheaply, whenever they want. | ||
| 351 | */ | ||
| 352 | u64 *ipath_statusp; | ||
| 353 | /* freeze msg if hw error put chip in freeze */ | ||
| 354 | char *ipath_freezemsg; | ||
| 355 | /* pci access data structure */ | ||
| 356 | struct pci_dev *pcidev; | ||
| 357 | struct cdev *cdev; | ||
| 358 | struct class_device *class_dev; | ||
| 359 | /* timer used to prevent stats overflow, error throttling, etc. */ | ||
| 360 | struct timer_list ipath_stats_timer; | ||
| 361 | /* check for stale messages in rcv queue */ | ||
| 362 | /* only allow one intr at a time. */ | ||
| 363 | unsigned long ipath_rcv_pending; | ||
| 364 | |||
| 365 | /* | ||
| 366 | * Shadow copies of registers; size indicates read access size. | ||
| 367 | * Most of them are readonly, but some are write-only register, | ||
| 368 | * where we manipulate the bits in the shadow copy, and then write | ||
| 369 | * the shadow copy to infinipath. | ||
| 370 | * | ||
| 371 | * We deliberately make most of these 32 bits, since they have | ||
| 372 | * restricted range. For any that we read, we won't to generate 32 | ||
| 373 | * bit accesses, since Opteron will generate 2 separate 32 bit HT | ||
| 374 | * transactions for a 64 bit read, and we want to avoid unnecessary | ||
| 375 | * HT transactions. | ||
| 376 | */ | ||
| 377 | |||
| 378 | /* This is the 64 bit group */ | ||
| 379 | |||
| 380 | /* | ||
| 381 | * shadow of pioavail, check to be sure it's large enough at | ||
| 382 | * init time. | ||
| 383 | */ | ||
| 384 | unsigned long ipath_pioavailshadow[8]; | ||
| 385 | /* shadow of kr_gpio_out, for rmw ops */ | ||
| 386 | u64 ipath_gpio_out; | ||
| 387 | /* kr_revision shadow */ | ||
| 388 | u64 ipath_revision; | ||
| 389 | /* | ||
| 390 | * shadow of ibcctrl, for interrupt handling of link changes, | ||
| 391 | * etc. | ||
| 392 | */ | ||
| 393 | u64 ipath_ibcctrl; | ||
| 394 | /* | ||
| 395 | * last ibcstatus, to suppress "duplicate" status change messages, | ||
| 396 | * mostly from 2 to 3 | ||
| 397 | */ | ||
| 398 | u64 ipath_lastibcstat; | ||
| 399 | /* hwerrmask shadow */ | ||
| 400 | ipath_err_t ipath_hwerrmask; | ||
| 401 | /* interrupt config reg shadow */ | ||
| 402 | u64 ipath_intconfig; | ||
| 403 | /* kr_sendpiobufbase value */ | ||
| 404 | u64 ipath_piobufbase; | ||
| 405 | |||
| 406 | /* these are the "32 bit" regs */ | ||
| 407 | |||
| 408 | /* | ||
| 409 | * number of GUIDs in the flash for this interface; may need some | ||
| 410 | * rethinking for setting on other ifaces | ||
| 411 | */ | ||
| 412 | u32 ipath_nguid; | ||
| 413 | /* | ||
| 414 | * the following two are 32-bit bitmasks, but {test,clear,set}_bit | ||
| 415 | * all expect bit fields to be "unsigned long" | ||
| 416 | */ | ||
| 417 | /* shadow kr_rcvctrl */ | ||
| 418 | unsigned long ipath_rcvctrl; | ||
| 419 | /* shadow kr_sendctrl */ | ||
| 420 | unsigned long ipath_sendctrl; | ||
| 421 | |||
| 422 | /* value we put in kr_rcvhdrcnt */ | ||
| 423 | u32 ipath_rcvhdrcnt; | ||
| 424 | /* value we put in kr_rcvhdrsize */ | ||
| 425 | u32 ipath_rcvhdrsize; | ||
| 426 | /* value we put in kr_rcvhdrentsize */ | ||
| 427 | u32 ipath_rcvhdrentsize; | ||
| 428 | /* offset of last entry in rcvhdrq */ | ||
| 429 | u32 ipath_hdrqlast; | ||
| 430 | /* kr_portcnt value */ | ||
| 431 | u32 ipath_portcnt; | ||
| 432 | /* kr_pagealign value */ | ||
| 433 | u32 ipath_palign; | ||
| 434 | /* number of "2KB" PIO buffers */ | ||
| 435 | u32 ipath_piobcnt2k; | ||
| 436 | /* size in bytes of "2KB" PIO buffers */ | ||
| 437 | u32 ipath_piosize2k; | ||
| 438 | /* number of "4KB" PIO buffers */ | ||
| 439 | u32 ipath_piobcnt4k; | ||
| 440 | /* size in bytes of "4KB" PIO buffers */ | ||
| 441 | u32 ipath_piosize4k; | ||
| 442 | /* kr_rcvegrbase value */ | ||
| 443 | u32 ipath_rcvegrbase; | ||
| 444 | /* kr_rcvegrcnt value */ | ||
| 445 | u32 ipath_rcvegrcnt; | ||
| 446 | /* kr_rcvtidbase value */ | ||
| 447 | u32 ipath_rcvtidbase; | ||
| 448 | /* kr_rcvtidcnt value */ | ||
| 449 | u32 ipath_rcvtidcnt; | ||
| 450 | /* kr_sendregbase */ | ||
| 451 | u32 ipath_sregbase; | ||
| 452 | /* kr_userregbase */ | ||
| 453 | u32 ipath_uregbase; | ||
| 454 | /* kr_counterregbase */ | ||
| 455 | u32 ipath_cregbase; | ||
| 456 | /* shadow the control register contents */ | ||
| 457 | u32 ipath_control; | ||
| 458 | /* shadow the gpio output contents */ | ||
| 459 | u32 ipath_extctrl; | ||
| 460 | /* PCI revision register (HTC rev on FPGA) */ | ||
| 461 | u32 ipath_pcirev; | ||
| 462 | |||
| 463 | /* chip address space used by 4k pio buffers */ | ||
| 464 | u32 ipath_4kalign; | ||
| 465 | /* The MTU programmed for this unit */ | ||
| 466 | u32 ipath_ibmtu; | ||
| 467 | /* | ||
| 468 | * The max size IB packet, included IB headers that we can send. | ||
| 469 | * Starts same as ipath_piosize, but is affected when ibmtu is | ||
| 470 | * changed, or by size of eager buffers | ||
| 471 | */ | ||
| 472 | u32 ipath_ibmaxlen; | ||
| 473 | /* | ||
| 474 | * ibmaxlen at init time, limited by chip and by receive buffer | ||
| 475 | * size. Not changed after init. | ||
| 476 | */ | ||
| 477 | u32 ipath_init_ibmaxlen; | ||
| 478 | /* size of each rcvegrbuffer */ | ||
| 479 | u32 ipath_rcvegrbufsize; | ||
| 480 | /* width (2,4,8,16,32) from HT config reg */ | ||
| 481 | u32 ipath_htwidth; | ||
| 482 | /* HT speed (200,400,800,1000) from HT config */ | ||
| 483 | u32 ipath_htspeed; | ||
| 484 | /* ports waiting for PIOavail intr */ | ||
| 485 | unsigned long ipath_portpiowait; | ||
| 486 | /* | ||
| 487 | * number of sequential ibcstatus change for polling active/quiet | ||
| 488 | * (i.e., link not coming up). | ||
| 489 | */ | ||
| 490 | u32 ipath_ibpollcnt; | ||
| 491 | /* low and high portions of MSI capability/vector */ | ||
| 492 | u32 ipath_msi_lo; | ||
| 493 | /* saved after PCIe init for restore after reset */ | ||
| 494 | u32 ipath_msi_hi; | ||
| 495 | /* MSI data (vector) saved for restore */ | ||
| 496 | u16 ipath_msi_data; | ||
| 497 | /* MLID programmed for this instance */ | ||
| 498 | u16 ipath_mlid; | ||
| 499 | /* LID programmed for this instance */ | ||
| 500 | u16 ipath_lid; | ||
| 501 | /* list of pkeys programmed; 0 if not set */ | ||
| 502 | u16 ipath_pkeys[4]; | ||
| 503 | /* ASCII serial number, from flash */ | ||
| 504 | u8 ipath_serial[12]; | ||
| 505 | /* human readable board version */ | ||
| 506 | u8 ipath_boardversion[80]; | ||
| 507 | /* chip major rev, from ipath_revision */ | ||
| 508 | u8 ipath_majrev; | ||
| 509 | /* chip minor rev, from ipath_revision */ | ||
| 510 | u8 ipath_minrev; | ||
| 511 | /* board rev, from ipath_revision */ | ||
| 512 | u8 ipath_boardrev; | ||
| 513 | /* unit # of this chip, if present */ | ||
| 514 | int ipath_unit; | ||
| 515 | /* saved for restore after reset */ | ||
| 516 | u8 ipath_pci_cacheline; | ||
| 517 | /* LID mask control */ | ||
| 518 | u8 ipath_lmc; | ||
| 519 | }; | ||
| 520 | |||
| 521 | extern volatile __le64 *ipath_port0_rcvhdrtail; | ||
| 522 | extern dma_addr_t ipath_port0_rcvhdrtail_dma; | ||
| 523 | |||
| 524 | #define IPATH_PORT0_RCVHDRTAIL_SIZE PAGE_SIZE | ||
| 525 | |||
| 526 | extern struct list_head ipath_dev_list; | ||
| 527 | extern spinlock_t ipath_devs_lock; | ||
| 528 | extern struct ipath_devdata *ipath_lookup(int unit); | ||
| 529 | |||
| 530 | extern u16 ipath_layer_rcv_opcode; | ||
| 531 | extern int ipath_verbs_registered; | ||
| 532 | extern int __ipath_layer_intr(struct ipath_devdata *, u32); | ||
| 533 | extern int ipath_layer_intr(struct ipath_devdata *, u32); | ||
| 534 | extern int __ipath_layer_rcv(struct ipath_devdata *, void *, | ||
| 535 | struct sk_buff *); | ||
| 536 | extern int __ipath_layer_rcv_lid(struct ipath_devdata *, void *); | ||
| 537 | extern int __ipath_verbs_piobufavail(struct ipath_devdata *); | ||
| 538 | extern int __ipath_verbs_rcv(struct ipath_devdata *, void *, void *, u32); | ||
| 539 | |||
| 540 | void ipath_layer_add(struct ipath_devdata *); | ||
| 541 | void ipath_layer_del(struct ipath_devdata *); | ||
| 542 | |||
| 543 | int ipath_init_chip(struct ipath_devdata *, int); | ||
| 544 | int ipath_enable_wc(struct ipath_devdata *dd); | ||
| 545 | void ipath_disable_wc(struct ipath_devdata *dd); | ||
| 546 | int ipath_count_units(int *npresentp, int *nupp, u32 *maxportsp); | ||
| 547 | void ipath_shutdown_device(struct ipath_devdata *); | ||
| 548 | |||
| 549 | struct file_operations; | ||
| 550 | int ipath_cdev_init(int minor, char *name, struct file_operations *fops, | ||
| 551 | struct cdev **cdevp, struct class_device **class_devp); | ||
| 552 | void ipath_cdev_cleanup(struct cdev **cdevp, | ||
| 553 | struct class_device **class_devp); | ||
| 554 | |||
| 555 | int ipath_diag_init(void); | ||
| 556 | void ipath_diag_cleanup(void); | ||
| 557 | void ipath_diag_bringup_link(struct ipath_devdata *); | ||
| 558 | |||
| 559 | extern wait_queue_head_t ipath_sma_state_wait; | ||
| 560 | |||
| 561 | int ipath_user_add(struct ipath_devdata *dd); | ||
| 562 | void ipath_user_del(struct ipath_devdata *dd); | ||
| 563 | |||
| 564 | struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd, gfp_t); | ||
| 565 | |||
| 566 | extern int ipath_diag_inuse; | ||
| 567 | |||
| 568 | irqreturn_t ipath_intr(int irq, void *devid, struct pt_regs *regs); | ||
| 569 | void ipath_decode_err(char *buf, size_t blen, ipath_err_t err); | ||
| 570 | #if __IPATH_INFO || __IPATH_DBG | ||
| 571 | extern const char *ipath_ibcstatus_str[]; | ||
| 572 | #endif | ||
| 573 | |||
| 574 | /* clean up any per-chip chip-specific stuff */ | ||
| 575 | void ipath_chip_cleanup(struct ipath_devdata *); | ||
| 576 | /* clean up any chip type-specific stuff */ | ||
| 577 | void ipath_chip_done(void); | ||
| 578 | |||
| 579 | /* check to see if we have to force ordering for write combining */ | ||
| 580 | int ipath_unordered_wc(void); | ||
| 581 | |||
| 582 | void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, | ||
| 583 | unsigned cnt); | ||
| 584 | |||
| 585 | int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); | ||
| 586 | void ipath_free_pddata(struct ipath_devdata *, u32, int); | ||
| 587 | |||
| 588 | int ipath_parse_ushort(const char *str, unsigned short *valp); | ||
| 589 | |||
| 590 | int ipath_wait_linkstate(struct ipath_devdata *, u32, int); | ||
| 591 | void ipath_set_ib_lstate(struct ipath_devdata *, int); | ||
| 592 | void ipath_kreceive(struct ipath_devdata *); | ||
| 593 | int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); | ||
| 594 | int ipath_reset_device(int); | ||
| 595 | void ipath_get_faststats(unsigned long); | ||
| 596 | |||
| 597 | /* for use in system calls, where we want to know device type, etc. */ | ||
| 598 | #define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data) | ||
| 599 | |||
| 600 | /* | ||
| 601 | * values for ipath_flags | ||
| 602 | */ | ||
| 603 | /* The chip is up and initted */ | ||
| 604 | #define IPATH_INITTED 0x2 | ||
| 605 | /* set if any user code has set kr_rcvhdrsize */ | ||
| 606 | #define IPATH_RCVHDRSZ_SET 0x4 | ||
| 607 | /* The chip is present and valid for accesses */ | ||
| 608 | #define IPATH_PRESENT 0x8 | ||
| 609 | /* HT link0 is only 8 bits wide, ignore upper byte crc | ||
| 610 | * errors, etc. */ | ||
| 611 | #define IPATH_8BIT_IN_HT0 0x10 | ||
| 612 | /* HT link1 is only 8 bits wide, ignore upper byte crc | ||
| 613 | * errors, etc. */ | ||
| 614 | #define IPATH_8BIT_IN_HT1 0x20 | ||
| 615 | /* The link is down */ | ||
| 616 | #define IPATH_LINKDOWN 0x40 | ||
| 617 | /* The link level is up (0x11) */ | ||
| 618 | #define IPATH_LINKINIT 0x80 | ||
| 619 | /* The link is in the armed (0x21) state */ | ||
| 620 | #define IPATH_LINKARMED 0x100 | ||
| 621 | /* The link is in the active (0x31) state */ | ||
| 622 | #define IPATH_LINKACTIVE 0x200 | ||
| 623 | /* link current state is unknown */ | ||
| 624 | #define IPATH_LINKUNK 0x400 | ||
| 625 | /* no IB cable, or no device on IB cable */ | ||
| 626 | #define IPATH_NOCABLE 0x4000 | ||
| 627 | /* Supports port zero per packet receive interrupts via | ||
| 628 | * GPIO */ | ||
| 629 | #define IPATH_GPIO_INTR 0x8000 | ||
| 630 | /* uses the coded 4byte TID, not 8 byte */ | ||
| 631 | #define IPATH_4BYTE_TID 0x10000 | ||
| 632 | /* packet/word counters are 32 bit, else those 4 counters | ||
| 633 | * are 64bit */ | ||
| 634 | #define IPATH_32BITCOUNTERS 0x20000 | ||
| 635 | /* can miss port0 rx interrupts */ | ||
| 636 | #define IPATH_POLL_RX_INTR 0x40000 | ||
| 637 | #define IPATH_DISABLED 0x80000 /* administratively disabled */ | ||
| 638 | |||
| 639 | /* portdata flag bit offsets */ | ||
| 640 | /* waiting for a packet to arrive */ | ||
| 641 | #define IPATH_PORT_WAITING_RCV 2 | ||
| 642 | /* waiting for a PIO buffer to be available */ | ||
| 643 | #define IPATH_PORT_WAITING_PIO 3 | ||
| 644 | |||
| 645 | /* free up any allocated data at closes */ | ||
| 646 | void ipath_free_data(struct ipath_portdata *dd); | ||
| 647 | int ipath_waitfor_mdio_cmdready(struct ipath_devdata *); | ||
| 648 | int ipath_waitfor_complete(struct ipath_devdata *, ipath_kreg, u64, u64 *); | ||
| 649 | u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *); | ||
| 650 | /* init PE-800-specific func */ | ||
| 651 | void ipath_init_pe800_funcs(struct ipath_devdata *); | ||
| 652 | /* init HT-400-specific func */ | ||
| 653 | void ipath_init_ht400_funcs(struct ipath_devdata *); | ||
| 654 | void ipath_get_guid(struct ipath_devdata *); | ||
| 655 | u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); | ||
| 656 | |||
| 657 | /* | ||
| 658 | * number of words used for protocol header if not set by ipath_userinit(); | ||
| 659 | */ | ||
| 660 | #define IPATH_DFLT_RCVHDRSIZE 9 | ||
| 661 | |||
| 662 | #define IPATH_MDIO_CMD_WRITE 1 | ||
| 663 | #define IPATH_MDIO_CMD_READ 2 | ||
| 664 | #define IPATH_MDIO_CLD_DIV 25 /* to get 2.5 Mhz mdio clock */ | ||
| 665 | #define IPATH_MDIO_CMDVALID 0x40000000 /* bit 30 */ | ||
| 666 | #define IPATH_MDIO_DATAVALID 0x80000000 /* bit 31 */ | ||
| 667 | #define IPATH_MDIO_CTRL_STD 0x0 | ||
| 668 | |||
| 669 | static inline u64 ipath_mdio_req(int cmd, int dev, int reg, int data) | ||
| 670 | { | ||
| 671 | return (((u64) IPATH_MDIO_CLD_DIV) << 32) | | ||
| 672 | (cmd << 26) | | ||
| 673 | (dev << 21) | | ||
| 674 | (reg << 16) | | ||
| 675 | (data & 0xFFFF); | ||
| 676 | } | ||
| 677 | |||
| 678 | /* signal and fifo status, in bank 31 */ | ||
| 679 | #define IPATH_MDIO_CTRL_XGXS_REG_8 0x8 | ||
| 680 | /* controls loopback, redundancy */ | ||
| 681 | #define IPATH_MDIO_CTRL_8355_REG_1 0x10 | ||
| 682 | /* premph, encdec, etc. */ | ||
| 683 | #define IPATH_MDIO_CTRL_8355_REG_2 0x11 | ||
| 684 | /* Kchars, etc. */ | ||
| 685 | #define IPATH_MDIO_CTRL_8355_REG_6 0x15 | ||
| 686 | #define IPATH_MDIO_CTRL_8355_REG_9 0x18 | ||
| 687 | #define IPATH_MDIO_CTRL_8355_REG_10 0x1D | ||
| 688 | |||
| 689 | int ipath_get_user_pages(unsigned long, size_t, struct page **); | ||
| 690 | int ipath_get_user_pages_nocopy(unsigned long, struct page **); | ||
| 691 | void ipath_release_user_pages(struct page **, size_t); | ||
| 692 | void ipath_release_user_pages_on_close(struct page **, size_t); | ||
| 693 | int ipath_eeprom_read(struct ipath_devdata *, u8, void *, int); | ||
| 694 | int ipath_eeprom_write(struct ipath_devdata *, u8, const void *, int); | ||
| 695 | |||
| 696 | /* these are used for the registers that vary with port */ | ||
| 697 | void ipath_write_kreg_port(const struct ipath_devdata *, ipath_kreg, | ||
| 698 | unsigned, u64); | ||
| 699 | u64 ipath_read_kreg64_port(const struct ipath_devdata *, ipath_kreg, | ||
| 700 | unsigned); | ||
| 701 | |||
| 702 | /* | ||
| 703 | * We could have a single register get/put routine, that takes a group type, | ||
| 704 | * but this is somewhat clearer and cleaner. It also gives us some error | ||
| 705 | * checking. 64 bit register reads should always work, but are inefficient | ||
| 706 | * on opteron (the northbridge always generates 2 separate HT 32 bit reads), | ||
| 707 | * so we use kreg32 wherever possible. User register and counter register | ||
| 708 | * reads are always 32 bit reads, so only one form of those routines. | ||
| 709 | */ | ||
| 710 | |||
| 711 | /* | ||
| 712 | * At the moment, none of the s-registers are writable, so no | ||
| 713 | * ipath_write_sreg(), and none of the c-registers are writable, so no | ||
| 714 | * ipath_write_creg(). | ||
| 715 | */ | ||
| 716 | |||
| 717 | /** | ||
| 718 | * ipath_read_ureg32 - read 32-bit virtualized per-port register | ||
| 719 | * @dd: device | ||
| 720 | * @regno: register number | ||
| 721 | * @port: port number | ||
| 722 | * | ||
| 723 | * Return the contents of a register that is virtualized to be per port. | ||
| 724 | * Prints a debug message and returns -1 on errors (not distinguishable from | ||
| 725 | * valid contents at runtime; we may add a separate error variable at some | ||
| 726 | * point). | ||
| 727 | * | ||
| 728 | * This is normally not used by the kernel, but may be for debugging, and | ||
| 729 | * has a different implementation than user mode, which is why it's not in | ||
| 730 | * _common.h. | ||
| 731 | */ | ||
| 732 | static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd, | ||
| 733 | ipath_ureg regno, int port) | ||
| 734 | { | ||
| 735 | if (!dd->ipath_kregbase) | ||
| 736 | return 0; | ||
| 737 | |||
| 738 | return readl(regno + (u64 __iomem *) | ||
| 739 | (dd->ipath_uregbase + | ||
| 740 | (char __iomem *)dd->ipath_kregbase + | ||
| 741 | dd->ipath_palign * port)); | ||
| 742 | } | ||
| 743 | |||
| 744 | /** | ||
| 745 | * ipath_write_ureg - write 32-bit virtualized per-port register | ||
| 746 | * @dd: device | ||
| 747 | * @regno: register number | ||
| 748 | * @value: value | ||
| 749 | * @port: port | ||
| 750 | * | ||
| 751 | * Write the contents of a register that is virtualized to be per port. | ||
| 752 | */ | ||
| 753 | static inline void ipath_write_ureg(const struct ipath_devdata *dd, | ||
| 754 | ipath_ureg regno, u64 value, int port) | ||
| 755 | { | ||
| 756 | u64 __iomem *ubase = (u64 __iomem *) | ||
| 757 | (dd->ipath_uregbase + (char __iomem *) dd->ipath_kregbase + | ||
| 758 | dd->ipath_palign * port); | ||
| 759 | if (dd->ipath_kregbase) | ||
| 760 | writeq(value, &ubase[regno]); | ||
| 761 | } | ||
| 762 | |||
| 763 | static inline u32 ipath_read_kreg32(const struct ipath_devdata *dd, | ||
| 764 | ipath_kreg regno) | ||
| 765 | { | ||
| 766 | if (!dd->ipath_kregbase) | ||
| 767 | return -1; | ||
| 768 | return readl((u32 __iomem *) & dd->ipath_kregbase[regno]); | ||
| 769 | } | ||
| 770 | |||
| 771 | static inline u64 ipath_read_kreg64(const struct ipath_devdata *dd, | ||
| 772 | ipath_kreg regno) | ||
| 773 | { | ||
| 774 | if (!dd->ipath_kregbase) | ||
| 775 | return -1; | ||
| 776 | |||
| 777 | return readq(&dd->ipath_kregbase[regno]); | ||
| 778 | } | ||
| 779 | |||
| 780 | static inline void ipath_write_kreg(const struct ipath_devdata *dd, | ||
| 781 | ipath_kreg regno, u64 value) | ||
| 782 | { | ||
| 783 | if (dd->ipath_kregbase) | ||
| 784 | writeq(value, &dd->ipath_kregbase[regno]); | ||
| 785 | } | ||
| 786 | |||
| 787 | static inline u64 ipath_read_creg(const struct ipath_devdata *dd, | ||
| 788 | ipath_sreg regno) | ||
| 789 | { | ||
| 790 | if (!dd->ipath_kregbase) | ||
| 791 | return 0; | ||
| 792 | |||
| 793 | return readq(regno + (u64 __iomem *) | ||
| 794 | (dd->ipath_cregbase + | ||
| 795 | (char __iomem *)dd->ipath_kregbase)); | ||
| 796 | } | ||
| 797 | |||
| 798 | static inline u32 ipath_read_creg32(const struct ipath_devdata *dd, | ||
| 799 | ipath_sreg regno) | ||
| 800 | { | ||
| 801 | if (!dd->ipath_kregbase) | ||
| 802 | return 0; | ||
| 803 | return readl(regno + (u64 __iomem *) | ||
| 804 | (dd->ipath_cregbase + | ||
| 805 | (char __iomem *)dd->ipath_kregbase)); | ||
| 806 | } | ||
| 807 | |||
| 808 | /* | ||
| 809 | * sysfs interface. | ||
| 810 | */ | ||
| 811 | |||
| 812 | struct device_driver; | ||
| 813 | |||
| 814 | extern const char ipath_core_version[]; | ||
| 815 | |||
| 816 | int ipath_driver_create_group(struct device_driver *); | ||
| 817 | void ipath_driver_remove_group(struct device_driver *); | ||
| 818 | |||
| 819 | int ipath_device_create_group(struct device *, struct ipath_devdata *); | ||
| 820 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); | ||
| 821 | int ipath_expose_reset(struct device *); | ||
| 822 | |||
| 823 | int ipath_init_ipathfs(void); | ||
| 824 | void ipath_exit_ipathfs(void); | ||
| 825 | int ipathfs_add_device(struct ipath_devdata *); | ||
| 826 | int ipathfs_remove_device(struct ipath_devdata *); | ||
| 827 | |||
| 828 | /* | ||
| 829 | * Flush write combining store buffers (if present) and perform a write | ||
| 830 | * barrier. | ||
| 831 | */ | ||
| 832 | #if defined(CONFIG_X86_64) | ||
| 833 | #define ipath_flush_wc() asm volatile("sfence" ::: "memory") | ||
| 834 | #else | ||
| 835 | #define ipath_flush_wc() wmb() | ||
| 836 | #endif | ||
| 837 | |||
| 838 | extern unsigned ipath_debug; /* debugging bit mask */ | ||
| 839 | |||
| 840 | const char *ipath_get_unit_name(int unit); | ||
| 841 | |||
| 842 | extern struct mutex ipath_mutex; | ||
| 843 | |||
| 844 | #define IPATH_DRV_NAME "ipath_core" | ||
| 845 | #define IPATH_MAJOR 233 | ||
| 846 | #define IPATH_SMA_MINOR 128 | ||
| 847 | #define IPATH_DIAG_MINOR 129 | ||
| 848 | #define IPATH_NMINORS 130 | ||
| 849 | |||
| 850 | #define ipath_dev_err(dd,fmt,...) \ | ||
| 851 | do { \ | ||
| 852 | const struct ipath_devdata *__dd = (dd); \ | ||
| 853 | if (__dd->pcidev) \ | ||
| 854 | dev_err(&__dd->pcidev->dev, "%s: " fmt, \ | ||
| 855 | ipath_get_unit_name(__dd->ipath_unit), \ | ||
| 856 | ##__VA_ARGS__); \ | ||
| 857 | else \ | ||
| 858 | printk(KERN_ERR IPATH_DRV_NAME ": %s: " fmt, \ | ||
| 859 | ipath_get_unit_name(__dd->ipath_unit), \ | ||
| 860 | ##__VA_ARGS__); \ | ||
| 861 | } while (0) | ||
| 862 | |||
| 863 | #if _IPATH_DEBUGGING | ||
| 864 | |||
| 865 | # define __IPATH_DBG_WHICH(which,fmt,...) \ | ||
| 866 | do { \ | ||
| 867 | if(unlikely(ipath_debug&(which))) \ | ||
| 868 | printk(KERN_DEBUG IPATH_DRV_NAME ": %s: " fmt, \ | ||
| 869 | __func__,##__VA_ARGS__); \ | ||
| 870 | } while(0) | ||
| 871 | |||
| 872 | # define ipath_dbg(fmt,...) \ | ||
| 873 | __IPATH_DBG_WHICH(__IPATH_DBG,fmt,##__VA_ARGS__) | ||
| 874 | # define ipath_cdbg(which,fmt,...) \ | ||
| 875 | __IPATH_DBG_WHICH(__IPATH_##which##DBG,fmt,##__VA_ARGS__) | ||
| 876 | |||
| 877 | #else /* ! _IPATH_DEBUGGING */ | ||
| 878 | |||
| 879 | # define ipath_dbg(fmt,...) | ||
| 880 | # define ipath_cdbg(which,fmt,...) | ||
| 881 | |||
| 882 | #endif /* _IPATH_DEBUGGING */ | ||
| 883 | |||
| 884 | #endif /* _IPATH_KERNEL_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c new file mode 100644 index 000000000000..aa33b0e9f2f6 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_keys.c | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <asm/io.h> | ||
| 34 | |||
| 35 | #include "ipath_verbs.h" | ||
| 36 | |||
| 37 | /** | ||
| 38 | * ipath_alloc_lkey - allocate an lkey | ||
| 39 | * @rkt: lkey table in which to allocate the lkey | ||
| 40 | * @mr: memory region that this lkey protects | ||
| 41 | * | ||
| 42 | * Returns 1 if successful, otherwise returns 0. | ||
| 43 | */ | ||
| 44 | |||
| 45 | int ipath_alloc_lkey(struct ipath_lkey_table *rkt, struct ipath_mregion *mr) | ||
| 46 | { | ||
| 47 | unsigned long flags; | ||
| 48 | u32 r; | ||
| 49 | u32 n; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | spin_lock_irqsave(&rkt->lock, flags); | ||
| 53 | |||
| 54 | /* Find the next available LKEY */ | ||
| 55 | r = n = rkt->next; | ||
| 56 | for (;;) { | ||
| 57 | if (rkt->table[r] == NULL) | ||
| 58 | break; | ||
| 59 | r = (r + 1) & (rkt->max - 1); | ||
| 60 | if (r == n) { | ||
| 61 | spin_unlock_irqrestore(&rkt->lock, flags); | ||
| 62 | _VERBS_INFO("LKEY table full\n"); | ||
| 63 | ret = 0; | ||
| 64 | goto bail; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | rkt->next = (r + 1) & (rkt->max - 1); | ||
| 68 | /* | ||
| 69 | * Make sure lkey is never zero which is reserved to indicate an | ||
| 70 | * unrestricted LKEY. | ||
| 71 | */ | ||
| 72 | rkt->gen++; | ||
| 73 | mr->lkey = (r << (32 - ib_ipath_lkey_table_size)) | | ||
| 74 | ((((1 << (24 - ib_ipath_lkey_table_size)) - 1) & rkt->gen) | ||
| 75 | << 8); | ||
| 76 | if (mr->lkey == 0) { | ||
| 77 | mr->lkey |= 1 << 8; | ||
| 78 | rkt->gen++; | ||
| 79 | } | ||
| 80 | rkt->table[r] = mr; | ||
| 81 | spin_unlock_irqrestore(&rkt->lock, flags); | ||
| 82 | |||
| 83 | ret = 1; | ||
| 84 | |||
| 85 | bail: | ||
| 86 | return ret; | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * ipath_free_lkey - free an lkey | ||
| 91 | * @rkt: table from which to free the lkey | ||
| 92 | * @lkey: lkey id to free | ||
| 93 | */ | ||
| 94 | void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey) | ||
| 95 | { | ||
| 96 | unsigned long flags; | ||
| 97 | u32 r; | ||
| 98 | |||
| 99 | if (lkey == 0) | ||
| 100 | return; | ||
| 101 | r = lkey >> (32 - ib_ipath_lkey_table_size); | ||
| 102 | spin_lock_irqsave(&rkt->lock, flags); | ||
| 103 | rkt->table[r] = NULL; | ||
| 104 | spin_unlock_irqrestore(&rkt->lock, flags); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * ipath_lkey_ok - check IB SGE for validity and initialize | ||
| 109 | * @rkt: table containing lkey to check SGE against | ||
| 110 | * @isge: outgoing internal SGE | ||
| 111 | * @sge: SGE to check | ||
| 112 | * @acc: access flags | ||
| 113 | * | ||
| 114 | * Return 1 if valid and successful, otherwise returns 0. | ||
| 115 | * | ||
| 116 | * Check the IB SGE for validity and initialize our internal version | ||
| 117 | * of it. | ||
| 118 | */ | ||
| 119 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | ||
| 120 | struct ib_sge *sge, int acc) | ||
| 121 | { | ||
| 122 | struct ipath_mregion *mr; | ||
| 123 | size_t off; | ||
| 124 | int ret; | ||
| 125 | |||
| 126 | /* | ||
| 127 | * We use LKEY == zero to mean a physical kmalloc() address. | ||
| 128 | * This is a bit of a hack since we rely on dma_map_single() | ||
| 129 | * being reversible by calling bus_to_virt(). | ||
| 130 | */ | ||
| 131 | if (sge->lkey == 0) { | ||
| 132 | isge->mr = NULL; | ||
| 133 | isge->vaddr = bus_to_virt(sge->addr); | ||
| 134 | isge->length = sge->length; | ||
| 135 | isge->sge_length = sge->length; | ||
| 136 | ret = 1; | ||
| 137 | goto bail; | ||
| 138 | } | ||
| 139 | spin_lock(&rkt->lock); | ||
| 140 | mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))]; | ||
| 141 | spin_unlock(&rkt->lock); | ||
| 142 | if (unlikely(mr == NULL || mr->lkey != sge->lkey)) { | ||
| 143 | ret = 0; | ||
| 144 | goto bail; | ||
| 145 | } | ||
| 146 | |||
| 147 | off = sge->addr - mr->user_base; | ||
| 148 | if (unlikely(sge->addr < mr->user_base || | ||
| 149 | off + sge->length > mr->length || | ||
| 150 | (mr->access_flags & acc) != acc)) { | ||
| 151 | ret = 0; | ||
| 152 | goto bail; | ||
| 153 | } | ||
| 154 | |||
| 155 | off += mr->offset; | ||
| 156 | isge->mr = mr; | ||
| 157 | isge->m = 0; | ||
| 158 | isge->n = 0; | ||
| 159 | while (off >= mr->map[isge->m]->segs[isge->n].length) { | ||
| 160 | off -= mr->map[isge->m]->segs[isge->n].length; | ||
| 161 | isge->n++; | ||
| 162 | if (isge->n >= IPATH_SEGSZ) { | ||
| 163 | isge->m++; | ||
| 164 | isge->n = 0; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | isge->vaddr = mr->map[isge->m]->segs[isge->n].vaddr + off; | ||
| 168 | isge->length = mr->map[isge->m]->segs[isge->n].length - off; | ||
| 169 | isge->sge_length = sge->length; | ||
| 170 | |||
| 171 | ret = 1; | ||
| 172 | |||
| 173 | bail: | ||
| 174 | return ret; | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * ipath_rkey_ok - check the IB virtual address, length, and RKEY | ||
| 179 | * @dev: infiniband device | ||
| 180 | * @ss: SGE state | ||
| 181 | * @len: length of data | ||
| 182 | * @vaddr: virtual address to place data | ||
| 183 | * @rkey: rkey to check | ||
| 184 | * @acc: access flags | ||
| 185 | * | ||
| 186 | * Return 1 if successful, otherwise 0. | ||
| 187 | * | ||
| 188 | * The QP r_rq.lock should be held. | ||
| 189 | */ | ||
| 190 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | ||
| 191 | u32 len, u64 vaddr, u32 rkey, int acc) | ||
| 192 | { | ||
| 193 | struct ipath_lkey_table *rkt = &dev->lk_table; | ||
| 194 | struct ipath_sge *sge = &ss->sge; | ||
| 195 | struct ipath_mregion *mr; | ||
| 196 | size_t off; | ||
| 197 | int ret; | ||
| 198 | |||
| 199 | spin_lock(&rkt->lock); | ||
| 200 | mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))]; | ||
| 201 | spin_unlock(&rkt->lock); | ||
| 202 | if (unlikely(mr == NULL || mr->lkey != rkey)) { | ||
| 203 | ret = 0; | ||
| 204 | goto bail; | ||
| 205 | } | ||
| 206 | |||
| 207 | off = vaddr - mr->iova; | ||
| 208 | if (unlikely(vaddr < mr->iova || off + len > mr->length || | ||
| 209 | (mr->access_flags & acc) == 0)) { | ||
| 210 | ret = 0; | ||
| 211 | goto bail; | ||
| 212 | } | ||
| 213 | |||
| 214 | off += mr->offset; | ||
| 215 | sge->mr = mr; | ||
| 216 | sge->m = 0; | ||
| 217 | sge->n = 0; | ||
| 218 | while (off >= mr->map[sge->m]->segs[sge->n].length) { | ||
| 219 | off -= mr->map[sge->m]->segs[sge->n].length; | ||
| 220 | sge->n++; | ||
| 221 | if (sge->n >= IPATH_SEGSZ) { | ||
| 222 | sge->m++; | ||
| 223 | sge->n = 0; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | sge->vaddr = mr->map[sge->m]->segs[sge->n].vaddr + off; | ||
| 227 | sge->length = mr->map[sge->m]->segs[sge->n].length - off; | ||
| 228 | sge->sge_length = len; | ||
| 229 | ss->sg_list = NULL; | ||
| 230 | ss->num_sge = 1; | ||
| 231 | |||
| 232 | ret = 1; | ||
| 233 | |||
| 234 | bail: | ||
| 235 | return ret; | ||
| 236 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c new file mode 100644 index 000000000000..2cabf6340572 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_layer.c | |||
| @@ -0,0 +1,1515 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* | ||
| 34 | * These are the routines used by layered drivers, currently just the | ||
| 35 | * layered ethernet driver and verbs layer. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include <linux/io.h> | ||
| 39 | #include <linux/pci.h> | ||
| 40 | #include <asm/byteorder.h> | ||
| 41 | |||
| 42 | #include "ipath_kernel.h" | ||
| 43 | #include "ips_common.h" | ||
| 44 | #include "ipath_layer.h" | ||
| 45 | |||
| 46 | /* Acquire before ipath_devs_lock. */ | ||
| 47 | static DEFINE_MUTEX(ipath_layer_mutex); | ||
| 48 | |||
| 49 | u16 ipath_layer_rcv_opcode; | ||
| 50 | static int (*layer_intr)(void *, u32); | ||
| 51 | static int (*layer_rcv)(void *, void *, struct sk_buff *); | ||
| 52 | static int (*layer_rcv_lid)(void *, void *); | ||
| 53 | static int (*verbs_piobufavail)(void *); | ||
| 54 | static void (*verbs_rcv)(void *, void *, void *, u32); | ||
| 55 | int ipath_verbs_registered; | ||
| 56 | |||
| 57 | static void *(*layer_add_one)(int, struct ipath_devdata *); | ||
| 58 | static void (*layer_remove_one)(void *); | ||
| 59 | static void *(*verbs_add_one)(int, struct ipath_devdata *); | ||
| 60 | static void (*verbs_remove_one)(void *); | ||
| 61 | static void (*verbs_timer_cb)(void *); | ||
| 62 | |||
| 63 | int __ipath_layer_intr(struct ipath_devdata *dd, u32 arg) | ||
| 64 | { | ||
| 65 | int ret = -ENODEV; | ||
| 66 | |||
| 67 | if (dd->ipath_layer.l_arg && layer_intr) | ||
| 68 | ret = layer_intr(dd->ipath_layer.l_arg, arg); | ||
| 69 | |||
| 70 | return ret; | ||
| 71 | } | ||
| 72 | |||
| 73 | int ipath_layer_intr(struct ipath_devdata *dd, u32 arg) | ||
| 74 | { | ||
| 75 | int ret; | ||
| 76 | |||
| 77 | mutex_lock(&ipath_layer_mutex); | ||
| 78 | |||
| 79 | ret = __ipath_layer_intr(dd, arg); | ||
| 80 | |||
| 81 | mutex_unlock(&ipath_layer_mutex); | ||
| 82 | |||
| 83 | return ret; | ||
| 84 | } | ||
| 85 | |||
| 86 | int __ipath_layer_rcv(struct ipath_devdata *dd, void *hdr, | ||
| 87 | struct sk_buff *skb) | ||
| 88 | { | ||
| 89 | int ret = -ENODEV; | ||
| 90 | |||
| 91 | if (dd->ipath_layer.l_arg && layer_rcv) | ||
| 92 | ret = layer_rcv(dd->ipath_layer.l_arg, hdr, skb); | ||
| 93 | |||
| 94 | return ret; | ||
| 95 | } | ||
| 96 | |||
| 97 | int __ipath_layer_rcv_lid(struct ipath_devdata *dd, void *hdr) | ||
| 98 | { | ||
| 99 | int ret = -ENODEV; | ||
| 100 | |||
| 101 | if (dd->ipath_layer.l_arg && layer_rcv_lid) | ||
| 102 | ret = layer_rcv_lid(dd->ipath_layer.l_arg, hdr); | ||
| 103 | |||
| 104 | return ret; | ||
| 105 | } | ||
| 106 | |||
| 107 | int __ipath_verbs_piobufavail(struct ipath_devdata *dd) | ||
| 108 | { | ||
| 109 | int ret = -ENODEV; | ||
| 110 | |||
| 111 | if (dd->verbs_layer.l_arg && verbs_piobufavail) | ||
| 112 | ret = verbs_piobufavail(dd->verbs_layer.l_arg); | ||
| 113 | |||
| 114 | return ret; | ||
| 115 | } | ||
| 116 | |||
| 117 | int __ipath_verbs_rcv(struct ipath_devdata *dd, void *rc, void *ebuf, | ||
| 118 | u32 tlen) | ||
| 119 | { | ||
| 120 | int ret = -ENODEV; | ||
| 121 | |||
| 122 | if (dd->verbs_layer.l_arg && verbs_rcv) { | ||
| 123 | verbs_rcv(dd->verbs_layer.l_arg, rc, ebuf, tlen); | ||
| 124 | ret = 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | return ret; | ||
| 128 | } | ||
| 129 | |||
| 130 | int ipath_layer_set_linkstate(struct ipath_devdata *dd, u8 newstate) | ||
| 131 | { | ||
| 132 | u32 lstate; | ||
| 133 | int ret; | ||
| 134 | |||
| 135 | switch (newstate) { | ||
| 136 | case IPATH_IB_LINKDOWN: | ||
| 137 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL << | ||
| 138 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | ||
| 139 | /* don't wait */ | ||
| 140 | ret = 0; | ||
| 141 | goto bail; | ||
| 142 | |||
| 143 | case IPATH_IB_LINKDOWN_SLEEP: | ||
| 144 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_SLEEP << | ||
| 145 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | ||
| 146 | /* don't wait */ | ||
| 147 | ret = 0; | ||
| 148 | goto bail; | ||
| 149 | |||
| 150 | case IPATH_IB_LINKDOWN_DISABLE: | ||
| 151 | ipath_set_ib_lstate(dd, | ||
| 152 | INFINIPATH_IBCC_LINKINITCMD_DISABLE << | ||
| 153 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | ||
| 154 | /* don't wait */ | ||
| 155 | ret = 0; | ||
| 156 | goto bail; | ||
| 157 | |||
| 158 | case IPATH_IB_LINKINIT: | ||
| 159 | if (dd->ipath_flags & IPATH_LINKINIT) { | ||
| 160 | ret = 0; | ||
| 161 | goto bail; | ||
| 162 | } | ||
| 163 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT << | ||
| 164 | INFINIPATH_IBCC_LINKCMD_SHIFT); | ||
| 165 | lstate = IPATH_LINKINIT; | ||
| 166 | break; | ||
| 167 | |||
| 168 | case IPATH_IB_LINKARM: | ||
| 169 | if (dd->ipath_flags & IPATH_LINKARMED) { | ||
| 170 | ret = 0; | ||
| 171 | goto bail; | ||
| 172 | } | ||
| 173 | if (!(dd->ipath_flags & | ||
| 174 | (IPATH_LINKINIT | IPATH_LINKACTIVE))) { | ||
| 175 | ret = -EINVAL; | ||
| 176 | goto bail; | ||
| 177 | } | ||
| 178 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ARMED << | ||
| 179 | INFINIPATH_IBCC_LINKCMD_SHIFT); | ||
| 180 | /* | ||
| 181 | * Since the port can transition to ACTIVE by receiving | ||
| 182 | * a non VL 15 packet, wait for either state. | ||
| 183 | */ | ||
| 184 | lstate = IPATH_LINKARMED | IPATH_LINKACTIVE; | ||
| 185 | break; | ||
| 186 | |||
| 187 | case IPATH_IB_LINKACTIVE: | ||
| 188 | if (dd->ipath_flags & IPATH_LINKACTIVE) { | ||
| 189 | ret = 0; | ||
| 190 | goto bail; | ||
| 191 | } | ||
| 192 | if (!(dd->ipath_flags & IPATH_LINKARMED)) { | ||
| 193 | ret = -EINVAL; | ||
| 194 | goto bail; | ||
| 195 | } | ||
| 196 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ACTIVE << | ||
| 197 | INFINIPATH_IBCC_LINKCMD_SHIFT); | ||
| 198 | lstate = IPATH_LINKACTIVE; | ||
| 199 | break; | ||
| 200 | |||
| 201 | default: | ||
| 202 | ipath_dbg("Invalid linkstate 0x%x requested\n", newstate); | ||
| 203 | ret = -EINVAL; | ||
| 204 | goto bail; | ||
| 205 | } | ||
| 206 | ret = ipath_wait_linkstate(dd, lstate, 2000); | ||
| 207 | |||
| 208 | bail: | ||
| 209 | return ret; | ||
| 210 | } | ||
| 211 | |||
| 212 | EXPORT_SYMBOL_GPL(ipath_layer_set_linkstate); | ||
| 213 | |||
| 214 | /** | ||
| 215 | * ipath_layer_set_mtu - set the MTU | ||
| 216 | * @dd: the infinipath device | ||
| 217 | * @arg: the new MTU | ||
| 218 | * | ||
| 219 | * we can handle "any" incoming size, the issue here is whether we | ||
| 220 | * need to restrict our outgoing size. For now, we don't do any | ||
| 221 | * sanity checking on this, and we don't deal with what happens to | ||
| 222 | * programs that are already running when the size changes. | ||
| 223 | * NOTE: changing the MTU will usually cause the IBC to go back to | ||
| 224 | * link initialize (IPATH_IBSTATE_INIT) state... | ||
| 225 | */ | ||
| 226 | int ipath_layer_set_mtu(struct ipath_devdata *dd, u16 arg) | ||
| 227 | { | ||
| 228 | u32 piosize; | ||
| 229 | int changed = 0; | ||
| 230 | int ret; | ||
| 231 | |||
| 232 | /* | ||
| 233 | * mtu is IB data payload max. It's the largest power of 2 less | ||
| 234 | * than piosize (or even larger, since it only really controls the | ||
| 235 | * largest we can receive; we can send the max of the mtu and | ||
| 236 | * piosize). We check that it's one of the valid IB sizes. | ||
| 237 | */ | ||
| 238 | if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 && | ||
| 239 | arg != 4096) { | ||
| 240 | ipath_dbg("Trying to set invalid mtu %u, failing\n", arg); | ||
| 241 | ret = -EINVAL; | ||
| 242 | goto bail; | ||
| 243 | } | ||
| 244 | if (dd->ipath_ibmtu == arg) { | ||
| 245 | ret = 0; /* same as current */ | ||
| 246 | goto bail; | ||
| 247 | } | ||
| 248 | |||
| 249 | piosize = dd->ipath_ibmaxlen; | ||
| 250 | dd->ipath_ibmtu = arg; | ||
| 251 | |||
| 252 | if (arg >= (piosize - IPATH_PIO_MAXIBHDR)) { | ||
| 253 | /* Only if it's not the initial value (or reset to it) */ | ||
| 254 | if (piosize != dd->ipath_init_ibmaxlen) { | ||
| 255 | dd->ipath_ibmaxlen = piosize; | ||
| 256 | changed = 1; | ||
| 257 | } | ||
| 258 | } else if ((arg + IPATH_PIO_MAXIBHDR) != dd->ipath_ibmaxlen) { | ||
| 259 | piosize = arg + IPATH_PIO_MAXIBHDR; | ||
| 260 | ipath_cdbg(VERBOSE, "ibmaxlen was 0x%x, setting to 0x%x " | ||
| 261 | "(mtu 0x%x)\n", dd->ipath_ibmaxlen, piosize, | ||
| 262 | arg); | ||
| 263 | dd->ipath_ibmaxlen = piosize; | ||
| 264 | changed = 1; | ||
| 265 | } | ||
| 266 | |||
| 267 | if (changed) { | ||
| 268 | /* | ||
| 269 | * set the IBC maxpktlength to the size of our pio | ||
| 270 | * buffers in words | ||
| 271 | */ | ||
| 272 | u64 ibc = dd->ipath_ibcctrl; | ||
| 273 | ibc &= ~(INFINIPATH_IBCC_MAXPKTLEN_MASK << | ||
| 274 | INFINIPATH_IBCC_MAXPKTLEN_SHIFT); | ||
| 275 | |||
| 276 | piosize = piosize - 2 * sizeof(u32); /* ignore pbc */ | ||
| 277 | dd->ipath_ibmaxlen = piosize; | ||
| 278 | piosize /= sizeof(u32); /* in words */ | ||
| 279 | /* | ||
| 280 | * for ICRC, which we only send in diag test pkt mode, and | ||
| 281 | * we don't need to worry about that for mtu | ||
| 282 | */ | ||
| 283 | piosize += 1; | ||
| 284 | |||
| 285 | ibc |= piosize << INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
| 286 | dd->ipath_ibcctrl = ibc; | ||
| 287 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
| 288 | dd->ipath_ibcctrl); | ||
| 289 | dd->ipath_f_tidtemplate(dd); | ||
| 290 | } | ||
| 291 | |||
| 292 | ret = 0; | ||
| 293 | |||
| 294 | bail: | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | |||
| 298 | EXPORT_SYMBOL_GPL(ipath_layer_set_mtu); | ||
| 299 | |||
| 300 | int ipath_set_sps_lid(struct ipath_devdata *dd, u32 arg, u8 lmc) | ||
| 301 | { | ||
| 302 | ipath_stats.sps_lid[dd->ipath_unit] = arg; | ||
| 303 | dd->ipath_lid = arg; | ||
| 304 | dd->ipath_lmc = lmc; | ||
| 305 | |||
| 306 | mutex_lock(&ipath_layer_mutex); | ||
| 307 | |||
| 308 | if (dd->ipath_layer.l_arg && layer_intr) | ||
| 309 | layer_intr(dd->ipath_layer.l_arg, IPATH_LAYER_INT_LID); | ||
| 310 | |||
| 311 | mutex_unlock(&ipath_layer_mutex); | ||
| 312 | |||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | |||
| 316 | EXPORT_SYMBOL_GPL(ipath_set_sps_lid); | ||
| 317 | |||
| 318 | int ipath_layer_set_guid(struct ipath_devdata *dd, __be64 guid) | ||
| 319 | { | ||
| 320 | /* XXX - need to inform anyone who cares this just happened. */ | ||
| 321 | dd->ipath_guid = guid; | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | EXPORT_SYMBOL_GPL(ipath_layer_set_guid); | ||
| 326 | |||
| 327 | __be64 ipath_layer_get_guid(struct ipath_devdata *dd) | ||
| 328 | { | ||
| 329 | return dd->ipath_guid; | ||
| 330 | } | ||
| 331 | |||
| 332 | EXPORT_SYMBOL_GPL(ipath_layer_get_guid); | ||
| 333 | |||
| 334 | u32 ipath_layer_get_nguid(struct ipath_devdata *dd) | ||
| 335 | { | ||
| 336 | return dd->ipath_nguid; | ||
| 337 | } | ||
| 338 | |||
| 339 | EXPORT_SYMBOL_GPL(ipath_layer_get_nguid); | ||
| 340 | |||
| 341 | int ipath_layer_query_device(struct ipath_devdata *dd, u32 * vendor, | ||
| 342 | u32 * boardrev, u32 * majrev, u32 * minrev) | ||
| 343 | { | ||
| 344 | *vendor = dd->ipath_vendorid; | ||
| 345 | *boardrev = dd->ipath_boardrev; | ||
| 346 | *majrev = dd->ipath_majrev; | ||
| 347 | *minrev = dd->ipath_minrev; | ||
| 348 | |||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | EXPORT_SYMBOL_GPL(ipath_layer_query_device); | ||
| 353 | |||
| 354 | u32 ipath_layer_get_flags(struct ipath_devdata *dd) | ||
| 355 | { | ||
| 356 | return dd->ipath_flags; | ||
| 357 | } | ||
| 358 | |||
| 359 | EXPORT_SYMBOL_GPL(ipath_layer_get_flags); | ||
| 360 | |||
| 361 | struct device *ipath_layer_get_device(struct ipath_devdata *dd) | ||
| 362 | { | ||
| 363 | return &dd->pcidev->dev; | ||
| 364 | } | ||
| 365 | |||
| 366 | EXPORT_SYMBOL_GPL(ipath_layer_get_device); | ||
| 367 | |||
| 368 | u16 ipath_layer_get_deviceid(struct ipath_devdata *dd) | ||
| 369 | { | ||
| 370 | return dd->ipath_deviceid; | ||
| 371 | } | ||
| 372 | |||
| 373 | EXPORT_SYMBOL_GPL(ipath_layer_get_deviceid); | ||
| 374 | |||
| 375 | u64 ipath_layer_get_lastibcstat(struct ipath_devdata *dd) | ||
| 376 | { | ||
| 377 | return dd->ipath_lastibcstat; | ||
| 378 | } | ||
| 379 | |||
| 380 | EXPORT_SYMBOL_GPL(ipath_layer_get_lastibcstat); | ||
| 381 | |||
| 382 | u32 ipath_layer_get_ibmtu(struct ipath_devdata *dd) | ||
| 383 | { | ||
| 384 | return dd->ipath_ibmtu; | ||
| 385 | } | ||
| 386 | |||
| 387 | EXPORT_SYMBOL_GPL(ipath_layer_get_ibmtu); | ||
| 388 | |||
| 389 | void ipath_layer_add(struct ipath_devdata *dd) | ||
| 390 | { | ||
| 391 | mutex_lock(&ipath_layer_mutex); | ||
| 392 | |||
| 393 | if (layer_add_one) | ||
| 394 | dd->ipath_layer.l_arg = | ||
| 395 | layer_add_one(dd->ipath_unit, dd); | ||
| 396 | |||
| 397 | if (verbs_add_one) | ||
| 398 | dd->verbs_layer.l_arg = | ||
| 399 | verbs_add_one(dd->ipath_unit, dd); | ||
| 400 | |||
| 401 | mutex_unlock(&ipath_layer_mutex); | ||
| 402 | } | ||
| 403 | |||
| 404 | void ipath_layer_del(struct ipath_devdata *dd) | ||
| 405 | { | ||
| 406 | mutex_lock(&ipath_layer_mutex); | ||
| 407 | |||
| 408 | if (dd->ipath_layer.l_arg && layer_remove_one) { | ||
| 409 | layer_remove_one(dd->ipath_layer.l_arg); | ||
| 410 | dd->ipath_layer.l_arg = NULL; | ||
| 411 | } | ||
| 412 | |||
| 413 | if (dd->verbs_layer.l_arg && verbs_remove_one) { | ||
| 414 | verbs_remove_one(dd->verbs_layer.l_arg); | ||
| 415 | dd->verbs_layer.l_arg = NULL; | ||
| 416 | } | ||
| 417 | |||
| 418 | mutex_unlock(&ipath_layer_mutex); | ||
| 419 | } | ||
| 420 | |||
| 421 | int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *), | ||
| 422 | void (*l_remove)(void *), | ||
| 423 | int (*l_intr)(void *, u32), | ||
| 424 | int (*l_rcv)(void *, void *, struct sk_buff *), | ||
| 425 | u16 l_rcv_opcode, | ||
| 426 | int (*l_rcv_lid)(void *, void *)) | ||
| 427 | { | ||
| 428 | struct ipath_devdata *dd, *tmp; | ||
| 429 | unsigned long flags; | ||
| 430 | |||
| 431 | mutex_lock(&ipath_layer_mutex); | ||
| 432 | |||
| 433 | layer_add_one = l_add; | ||
| 434 | layer_remove_one = l_remove; | ||
| 435 | layer_intr = l_intr; | ||
| 436 | layer_rcv = l_rcv; | ||
| 437 | layer_rcv_lid = l_rcv_lid; | ||
| 438 | ipath_layer_rcv_opcode = l_rcv_opcode; | ||
| 439 | |||
| 440 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 441 | |||
| 442 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 443 | if (!(dd->ipath_flags & IPATH_INITTED)) | ||
| 444 | continue; | ||
| 445 | |||
| 446 | if (dd->ipath_layer.l_arg) | ||
| 447 | continue; | ||
| 448 | |||
| 449 | if (!(*dd->ipath_statusp & IPATH_STATUS_SMA)) | ||
| 450 | *dd->ipath_statusp |= IPATH_STATUS_OIB_SMA; | ||
| 451 | |||
| 452 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 453 | dd->ipath_layer.l_arg = l_add(dd->ipath_unit, dd); | ||
| 454 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 455 | } | ||
| 456 | |||
| 457 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 458 | mutex_unlock(&ipath_layer_mutex); | ||
| 459 | |||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | |||
| 463 | EXPORT_SYMBOL_GPL(ipath_layer_register); | ||
| 464 | |||
| 465 | void ipath_layer_unregister(void) | ||
| 466 | { | ||
| 467 | struct ipath_devdata *dd, *tmp; | ||
| 468 | unsigned long flags; | ||
| 469 | |||
| 470 | mutex_lock(&ipath_layer_mutex); | ||
| 471 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 472 | |||
| 473 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 474 | if (dd->ipath_layer.l_arg && layer_remove_one) { | ||
| 475 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 476 | layer_remove_one(dd->ipath_layer.l_arg); | ||
| 477 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 478 | dd->ipath_layer.l_arg = NULL; | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 483 | |||
| 484 | layer_add_one = NULL; | ||
| 485 | layer_remove_one = NULL; | ||
| 486 | layer_intr = NULL; | ||
| 487 | layer_rcv = NULL; | ||
| 488 | layer_rcv_lid = NULL; | ||
| 489 | |||
| 490 | mutex_unlock(&ipath_layer_mutex); | ||
| 491 | } | ||
| 492 | |||
| 493 | EXPORT_SYMBOL_GPL(ipath_layer_unregister); | ||
| 494 | |||
| 495 | static void __ipath_verbs_timer(unsigned long arg) | ||
| 496 | { | ||
| 497 | struct ipath_devdata *dd = (struct ipath_devdata *) arg; | ||
| 498 | |||
| 499 | /* | ||
| 500 | * If port 0 receive packet interrupts are not available, or | ||
| 501 | * can be missed, poll the receive queue | ||
| 502 | */ | ||
| 503 | if (dd->ipath_flags & IPATH_POLL_RX_INTR) | ||
| 504 | ipath_kreceive(dd); | ||
| 505 | |||
| 506 | /* Handle verbs layer timeouts. */ | ||
| 507 | if (dd->verbs_layer.l_arg && verbs_timer_cb) | ||
| 508 | verbs_timer_cb(dd->verbs_layer.l_arg); | ||
| 509 | |||
| 510 | mod_timer(&dd->verbs_layer.l_timer, jiffies + 1); | ||
| 511 | } | ||
| 512 | |||
| 513 | /** | ||
| 514 | * ipath_verbs_register - verbs layer registration | ||
| 515 | * @l_piobufavail: callback for when PIO buffers become available | ||
| 516 | * @l_rcv: callback for receiving a packet | ||
| 517 | * @l_timer_cb: timer callback | ||
| 518 | * @ipath_devdata: device data structure is put here | ||
| 519 | */ | ||
| 520 | int ipath_verbs_register(void *(*l_add)(int, struct ipath_devdata *), | ||
| 521 | void (*l_remove)(void *arg), | ||
| 522 | int (*l_piobufavail) (void *arg), | ||
| 523 | void (*l_rcv) (void *arg, void *rhdr, | ||
| 524 | void *data, u32 tlen), | ||
| 525 | void (*l_timer_cb) (void *arg)) | ||
| 526 | { | ||
| 527 | struct ipath_devdata *dd, *tmp; | ||
| 528 | unsigned long flags; | ||
| 529 | |||
| 530 | mutex_lock(&ipath_layer_mutex); | ||
| 531 | |||
| 532 | verbs_add_one = l_add; | ||
| 533 | verbs_remove_one = l_remove; | ||
| 534 | verbs_piobufavail = l_piobufavail; | ||
| 535 | verbs_rcv = l_rcv; | ||
| 536 | verbs_timer_cb = l_timer_cb; | ||
| 537 | |||
| 538 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 539 | |||
| 540 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 541 | if (!(dd->ipath_flags & IPATH_INITTED)) | ||
| 542 | continue; | ||
| 543 | |||
| 544 | if (dd->verbs_layer.l_arg) | ||
| 545 | continue; | ||
| 546 | |||
| 547 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 548 | dd->verbs_layer.l_arg = l_add(dd->ipath_unit, dd); | ||
| 549 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 550 | } | ||
| 551 | |||
| 552 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 553 | mutex_unlock(&ipath_layer_mutex); | ||
| 554 | |||
| 555 | ipath_verbs_registered = 1; | ||
| 556 | |||
| 557 | return 0; | ||
| 558 | } | ||
| 559 | |||
| 560 | EXPORT_SYMBOL_GPL(ipath_verbs_register); | ||
| 561 | |||
| 562 | void ipath_verbs_unregister(void) | ||
| 563 | { | ||
| 564 | struct ipath_devdata *dd, *tmp; | ||
| 565 | unsigned long flags; | ||
| 566 | |||
| 567 | mutex_lock(&ipath_layer_mutex); | ||
| 568 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 569 | |||
| 570 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
| 571 | *dd->ipath_statusp &= ~IPATH_STATUS_OIB_SMA; | ||
| 572 | |||
| 573 | if (dd->verbs_layer.l_arg && verbs_remove_one) { | ||
| 574 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 575 | verbs_remove_one(dd->verbs_layer.l_arg); | ||
| 576 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
| 577 | dd->verbs_layer.l_arg = NULL; | ||
| 578 | } | ||
| 579 | } | ||
| 580 | |||
| 581 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
| 582 | |||
| 583 | verbs_add_one = NULL; | ||
| 584 | verbs_remove_one = NULL; | ||
| 585 | verbs_piobufavail = NULL; | ||
| 586 | verbs_rcv = NULL; | ||
| 587 | verbs_timer_cb = NULL; | ||
| 588 | |||
| 589 | mutex_unlock(&ipath_layer_mutex); | ||
| 590 | } | ||
| 591 | |||
| 592 | EXPORT_SYMBOL_GPL(ipath_verbs_unregister); | ||
| 593 | |||
| 594 | int ipath_layer_open(struct ipath_devdata *dd, u32 * pktmax) | ||
| 595 | { | ||
| 596 | int ret; | ||
| 597 | u32 intval = 0; | ||
| 598 | |||
| 599 | mutex_lock(&ipath_layer_mutex); | ||
| 600 | |||
| 601 | if (!dd->ipath_layer.l_arg) { | ||
| 602 | ret = -EINVAL; | ||
| 603 | goto bail; | ||
| 604 | } | ||
| 605 | |||
| 606 | ret = ipath_setrcvhdrsize(dd, NUM_OF_EXTRA_WORDS_IN_HEADER_QUEUE); | ||
| 607 | |||
| 608 | if (ret < 0) | ||
| 609 | goto bail; | ||
| 610 | |||
| 611 | *pktmax = dd->ipath_ibmaxlen; | ||
| 612 | |||
| 613 | if (*dd->ipath_statusp & IPATH_STATUS_IB_READY) | ||
| 614 | intval |= IPATH_LAYER_INT_IF_UP; | ||
| 615 | if (ipath_stats.sps_lid[dd->ipath_unit]) | ||
| 616 | intval |= IPATH_LAYER_INT_LID; | ||
| 617 | if (ipath_stats.sps_mlid[dd->ipath_unit]) | ||
| 618 | intval |= IPATH_LAYER_INT_BCAST; | ||
| 619 | /* | ||
| 620 | * do this on open, in case low level is already up and | ||
| 621 | * just layered driver was reloaded, etc. | ||
| 622 | */ | ||
| 623 | if (intval) | ||
| 624 | layer_intr(dd->ipath_layer.l_arg, intval); | ||
| 625 | |||
| 626 | ret = 0; | ||
| 627 | bail: | ||
| 628 | mutex_unlock(&ipath_layer_mutex); | ||
| 629 | |||
| 630 | return ret; | ||
| 631 | } | ||
| 632 | |||
| 633 | EXPORT_SYMBOL_GPL(ipath_layer_open); | ||
| 634 | |||
| 635 | u16 ipath_layer_get_lid(struct ipath_devdata *dd) | ||
| 636 | { | ||
| 637 | return dd->ipath_lid; | ||
| 638 | } | ||
| 639 | |||
| 640 | EXPORT_SYMBOL_GPL(ipath_layer_get_lid); | ||
| 641 | |||
| 642 | /** | ||
| 643 | * ipath_layer_get_mac - get the MAC address | ||
| 644 | * @dd: the infinipath device | ||
| 645 | * @mac: the MAC is put here | ||
| 646 | * | ||
| 647 | * This is the EUID-64 OUI octets (top 3), then | ||
| 648 | * skip the next 2 (which should both be zero or 0xff). | ||
| 649 | * The returned MAC is in network order | ||
| 650 | * mac points to at least 6 bytes of buffer | ||
| 651 | * We assume that by the time the LID is set, that the GUID is as valid | ||
| 652 | * as it's ever going to be, rather than adding yet another status bit. | ||
| 653 | */ | ||
| 654 | |||
| 655 | int ipath_layer_get_mac(struct ipath_devdata *dd, u8 * mac) | ||
| 656 | { | ||
| 657 | u8 *guid; | ||
| 658 | |||
| 659 | guid = (u8 *) &dd->ipath_guid; | ||
| 660 | |||
| 661 | mac[0] = guid[0]; | ||
| 662 | mac[1] = guid[1]; | ||
| 663 | mac[2] = guid[2]; | ||
| 664 | mac[3] = guid[5]; | ||
| 665 | mac[4] = guid[6]; | ||
| 666 | mac[5] = guid[7]; | ||
| 667 | if ((guid[3] || guid[4]) && !(guid[3] == 0xff && guid[4] == 0xff)) | ||
| 668 | ipath_dbg("Warning, guid bytes 3 and 4 not 0 or 0xffff: " | ||
| 669 | "%x %x\n", guid[3], guid[4]); | ||
| 670 | return 0; | ||
| 671 | } | ||
| 672 | |||
| 673 | EXPORT_SYMBOL_GPL(ipath_layer_get_mac); | ||
| 674 | |||
| 675 | u16 ipath_layer_get_bcast(struct ipath_devdata *dd) | ||
| 676 | { | ||
| 677 | return dd->ipath_mlid; | ||
| 678 | } | ||
| 679 | |||
| 680 | EXPORT_SYMBOL_GPL(ipath_layer_get_bcast); | ||
| 681 | |||
| 682 | u32 ipath_layer_get_cr_errpkey(struct ipath_devdata *dd) | ||
| 683 | { | ||
| 684 | return ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey); | ||
| 685 | } | ||
| 686 | |||
| 687 | EXPORT_SYMBOL_GPL(ipath_layer_get_cr_errpkey); | ||
| 688 | |||
| 689 | static void update_sge(struct ipath_sge_state *ss, u32 length) | ||
| 690 | { | ||
| 691 | struct ipath_sge *sge = &ss->sge; | ||
| 692 | |||
| 693 | sge->vaddr += length; | ||
| 694 | sge->length -= length; | ||
| 695 | sge->sge_length -= length; | ||
| 696 | if (sge->sge_length == 0) { | ||
| 697 | if (--ss->num_sge) | ||
| 698 | *sge = *ss->sg_list++; | ||
| 699 | } else if (sge->length == 0 && sge->mr != NULL) { | ||
| 700 | if (++sge->n >= IPATH_SEGSZ) { | ||
| 701 | if (++sge->m >= sge->mr->mapsz) | ||
| 702 | return; | ||
| 703 | sge->n = 0; | ||
| 704 | } | ||
| 705 | sge->vaddr = sge->mr->map[sge->m]->segs[sge->n].vaddr; | ||
| 706 | sge->length = sge->mr->map[sge->m]->segs[sge->n].length; | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 710 | #ifdef __LITTLE_ENDIAN | ||
| 711 | static inline u32 get_upper_bits(u32 data, u32 shift) | ||
| 712 | { | ||
| 713 | return data >> shift; | ||
| 714 | } | ||
| 715 | |||
| 716 | static inline u32 set_upper_bits(u32 data, u32 shift) | ||
| 717 | { | ||
| 718 | return data << shift; | ||
| 719 | } | ||
| 720 | |||
| 721 | static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off) | ||
| 722 | { | ||
| 723 | data <<= ((sizeof(u32) - n) * BITS_PER_BYTE); | ||
| 724 | data >>= ((sizeof(u32) - n - off) * BITS_PER_BYTE); | ||
| 725 | return data; | ||
| 726 | } | ||
| 727 | #else | ||
| 728 | static inline u32 get_upper_bits(u32 data, u32 shift) | ||
| 729 | { | ||
| 730 | return data << shift; | ||
| 731 | } | ||
| 732 | |||
| 733 | static inline u32 set_upper_bits(u32 data, u32 shift) | ||
| 734 | { | ||
| 735 | return data >> shift; | ||
| 736 | } | ||
| 737 | |||
| 738 | static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off) | ||
| 739 | { | ||
| 740 | data >>= ((sizeof(u32) - n) * BITS_PER_BYTE); | ||
| 741 | data <<= ((sizeof(u32) - n - off) * BITS_PER_BYTE); | ||
| 742 | return data; | ||
| 743 | } | ||
| 744 | #endif | ||
| 745 | |||
| 746 | static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | ||
| 747 | u32 length) | ||
| 748 | { | ||
| 749 | u32 extra = 0; | ||
| 750 | u32 data = 0; | ||
| 751 | u32 last; | ||
| 752 | |||
| 753 | while (1) { | ||
| 754 | u32 len = ss->sge.length; | ||
| 755 | u32 off; | ||
| 756 | |||
| 757 | BUG_ON(len == 0); | ||
| 758 | if (len > length) | ||
| 759 | len = length; | ||
| 760 | if (len > ss->sge.sge_length) | ||
| 761 | len = ss->sge.sge_length; | ||
| 762 | /* If the source address is not aligned, try to align it. */ | ||
| 763 | off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); | ||
| 764 | if (off) { | ||
| 765 | u32 *addr = (u32 *)((unsigned long)ss->sge.vaddr & | ||
| 766 | ~(sizeof(u32) - 1)); | ||
| 767 | u32 v = get_upper_bits(*addr, off * BITS_PER_BYTE); | ||
| 768 | u32 y; | ||
| 769 | |||
| 770 | y = sizeof(u32) - off; | ||
| 771 | if (len > y) | ||
| 772 | len = y; | ||
| 773 | if (len + extra >= sizeof(u32)) { | ||
| 774 | data |= set_upper_bits(v, extra * | ||
| 775 | BITS_PER_BYTE); | ||
| 776 | len = sizeof(u32) - extra; | ||
| 777 | if (len == length) { | ||
| 778 | last = data; | ||
| 779 | break; | ||
| 780 | } | ||
| 781 | __raw_writel(data, piobuf); | ||
| 782 | piobuf++; | ||
| 783 | extra = 0; | ||
| 784 | data = 0; | ||
| 785 | } else { | ||
| 786 | /* Clear unused upper bytes */ | ||
| 787 | data |= clear_upper_bytes(v, len, extra); | ||
| 788 | if (len == length) { | ||
| 789 | last = data; | ||
| 790 | break; | ||
| 791 | } | ||
| 792 | extra += len; | ||
| 793 | } | ||
| 794 | } else if (extra) { | ||
| 795 | /* Source address is aligned. */ | ||
| 796 | u32 *addr = (u32 *) ss->sge.vaddr; | ||
| 797 | int shift = extra * BITS_PER_BYTE; | ||
| 798 | int ushift = 32 - shift; | ||
| 799 | u32 l = len; | ||
| 800 | |||
| 801 | while (l >= sizeof(u32)) { | ||
| 802 | u32 v = *addr; | ||
| 803 | |||
| 804 | data |= set_upper_bits(v, shift); | ||
| 805 | __raw_writel(data, piobuf); | ||
| 806 | data = get_upper_bits(v, ushift); | ||
| 807 | piobuf++; | ||
| 808 | addr++; | ||
| 809 | l -= sizeof(u32); | ||
| 810 | } | ||
| 811 | /* | ||
| 812 | * We still have 'extra' number of bytes leftover. | ||
| 813 | */ | ||
| 814 | if (l) { | ||
| 815 | u32 v = *addr; | ||
| 816 | |||
| 817 | if (l + extra >= sizeof(u32)) { | ||
| 818 | data |= set_upper_bits(v, shift); | ||
| 819 | len -= l + extra - sizeof(u32); | ||
| 820 | if (len == length) { | ||
| 821 | last = data; | ||
| 822 | break; | ||
| 823 | } | ||
| 824 | __raw_writel(data, piobuf); | ||
| 825 | piobuf++; | ||
| 826 | extra = 0; | ||
| 827 | data = 0; | ||
| 828 | } else { | ||
| 829 | /* Clear unused upper bytes */ | ||
| 830 | data |= clear_upper_bytes(v, l, | ||
| 831 | extra); | ||
| 832 | if (len == length) { | ||
| 833 | last = data; | ||
| 834 | break; | ||
| 835 | } | ||
| 836 | extra += l; | ||
| 837 | } | ||
| 838 | } else if (len == length) { | ||
| 839 | last = data; | ||
| 840 | break; | ||
| 841 | } | ||
| 842 | } else if (len == length) { | ||
| 843 | u32 w; | ||
| 844 | |||
| 845 | /* | ||
| 846 | * Need to round up for the last dword in the | ||
| 847 | * packet. | ||
| 848 | */ | ||
| 849 | w = (len + 3) >> 2; | ||
| 850 | __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1); | ||
| 851 | piobuf += w - 1; | ||
| 852 | last = ((u32 *) ss->sge.vaddr)[w - 1]; | ||
| 853 | break; | ||
| 854 | } else { | ||
| 855 | u32 w = len >> 2; | ||
| 856 | |||
| 857 | __iowrite32_copy(piobuf, ss->sge.vaddr, w); | ||
| 858 | piobuf += w; | ||
| 859 | |||
| 860 | extra = len & (sizeof(u32) - 1); | ||
| 861 | if (extra) { | ||
| 862 | u32 v = ((u32 *) ss->sge.vaddr)[w]; | ||
| 863 | |||
| 864 | /* Clear unused upper bytes */ | ||
| 865 | data = clear_upper_bytes(v, extra, 0); | ||
| 866 | } | ||
| 867 | } | ||
| 868 | update_sge(ss, len); | ||
| 869 | length -= len; | ||
| 870 | } | ||
| 871 | /* must flush early everything before trigger word */ | ||
| 872 | ipath_flush_wc(); | ||
| 873 | __raw_writel(last, piobuf); | ||
| 874 | /* be sure trigger word is written */ | ||
| 875 | ipath_flush_wc(); | ||
| 876 | update_sge(ss, length); | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 880 | * ipath_verbs_send - send a packet from the verbs layer | ||
| 881 | * @dd: the infinipath device | ||
| 882 | * @hdrwords: the number of works in the header | ||
| 883 | * @hdr: the packet header | ||
| 884 | * @len: the length of the packet in bytes | ||
| 885 | * @ss: the SGE to send | ||
| 886 | * | ||
| 887 | * This is like ipath_sma_send_pkt() in that we need to be able to send | ||
| 888 | * packets after the chip is initialized (MADs) but also like | ||
| 889 | * ipath_layer_send_hdr() since its used by the verbs layer. | ||
| 890 | */ | ||
| 891 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | ||
| 892 | u32 *hdr, u32 len, struct ipath_sge_state *ss) | ||
| 893 | { | ||
| 894 | u32 __iomem *piobuf; | ||
| 895 | u32 plen; | ||
| 896 | int ret; | ||
| 897 | |||
| 898 | /* +1 is for the qword padding of pbc */ | ||
| 899 | plen = hdrwords + ((len + 3) >> 2) + 1; | ||
| 900 | if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) { | ||
| 901 | ipath_dbg("packet len 0x%x too long, failing\n", plen); | ||
| 902 | ret = -EINVAL; | ||
| 903 | goto bail; | ||
| 904 | } | ||
| 905 | |||
| 906 | /* Get a PIO buffer to use. */ | ||
| 907 | piobuf = ipath_getpiobuf(dd, NULL); | ||
| 908 | if (unlikely(piobuf == NULL)) { | ||
| 909 | ret = -EBUSY; | ||
| 910 | goto bail; | ||
| 911 | } | ||
| 912 | |||
| 913 | /* | ||
| 914 | * Write len to control qword, no flags. | ||
| 915 | * We have to flush after the PBC for correctness on some cpus | ||
| 916 | * or WC buffer can be written out of order. | ||
| 917 | */ | ||
| 918 | writeq(plen, piobuf); | ||
| 919 | ipath_flush_wc(); | ||
| 920 | piobuf += 2; | ||
| 921 | if (len == 0) { | ||
| 922 | /* | ||
| 923 | * If there is just the header portion, must flush before | ||
| 924 | * writing last word of header for correctness, and after | ||
| 925 | * the last header word (trigger word). | ||
| 926 | */ | ||
| 927 | __iowrite32_copy(piobuf, hdr, hdrwords - 1); | ||
| 928 | ipath_flush_wc(); | ||
| 929 | __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1); | ||
| 930 | ipath_flush_wc(); | ||
| 931 | ret = 0; | ||
| 932 | goto bail; | ||
| 933 | } | ||
| 934 | |||
| 935 | __iowrite32_copy(piobuf, hdr, hdrwords); | ||
| 936 | piobuf += hdrwords; | ||
| 937 | |||
| 938 | /* The common case is aligned and contained in one segment. */ | ||
| 939 | if (likely(ss->num_sge == 1 && len <= ss->sge.length && | ||
| 940 | !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { | ||
| 941 | u32 w; | ||
| 942 | |||
| 943 | /* Need to round up for the last dword in the packet. */ | ||
| 944 | w = (len + 3) >> 2; | ||
| 945 | __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1); | ||
| 946 | /* must flush early everything before trigger word */ | ||
| 947 | ipath_flush_wc(); | ||
| 948 | __raw_writel(((u32 *) ss->sge.vaddr)[w - 1], | ||
| 949 | piobuf + w - 1); | ||
| 950 | /* be sure trigger word is written */ | ||
| 951 | ipath_flush_wc(); | ||
| 952 | update_sge(ss, len); | ||
| 953 | ret = 0; | ||
| 954 | goto bail; | ||
| 955 | } | ||
| 956 | copy_io(piobuf, ss, len); | ||
| 957 | ret = 0; | ||
| 958 | |||
| 959 | bail: | ||
| 960 | return ret; | ||
| 961 | } | ||
| 962 | |||
| 963 | EXPORT_SYMBOL_GPL(ipath_verbs_send); | ||
| 964 | |||
| 965 | int ipath_layer_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | ||
| 966 | u64 *rwords, u64 *spkts, u64 *rpkts, | ||
| 967 | u64 *xmit_wait) | ||
| 968 | { | ||
| 969 | int ret; | ||
| 970 | |||
| 971 | if (!(dd->ipath_flags & IPATH_INITTED)) { | ||
| 972 | /* no hardware, freeze, etc. */ | ||
| 973 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
| 974 | ret = -EINVAL; | ||
| 975 | goto bail; | ||
| 976 | } | ||
| 977 | *swords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | ||
| 978 | *rwords = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | ||
| 979 | *spkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); | ||
| 980 | *rpkts = ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); | ||
| 981 | *xmit_wait = ipath_snap_cntr(dd, dd->ipath_cregs->cr_sendstallcnt); | ||
| 982 | |||
| 983 | ret = 0; | ||
| 984 | |||
| 985 | bail: | ||
| 986 | return ret; | ||
| 987 | } | ||
| 988 | |||
| 989 | EXPORT_SYMBOL_GPL(ipath_layer_snapshot_counters); | ||
| 990 | |||
| 991 | /** | ||
| 992 | * ipath_layer_get_counters - get various chip counters | ||
| 993 | * @dd: the infinipath device | ||
| 994 | * @cntrs: counters are placed here | ||
| 995 | * | ||
| 996 | * Return the counters needed by recv_pma_get_portcounters(). | ||
| 997 | */ | ||
| 998 | int ipath_layer_get_counters(struct ipath_devdata *dd, | ||
| 999 | struct ipath_layer_counters *cntrs) | ||
| 1000 | { | ||
| 1001 | int ret; | ||
| 1002 | |||
| 1003 | if (!(dd->ipath_flags & IPATH_INITTED)) { | ||
| 1004 | /* no hardware, freeze, etc. */ | ||
| 1005 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
| 1006 | ret = -EINVAL; | ||
| 1007 | goto bail; | ||
| 1008 | } | ||
| 1009 | cntrs->symbol_error_counter = | ||
| 1010 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_ibsymbolerrcnt); | ||
| 1011 | cntrs->link_error_recovery_counter = | ||
| 1012 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt); | ||
| 1013 | cntrs->link_downed_counter = | ||
| 1014 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkdowncnt); | ||
| 1015 | cntrs->port_rcv_errors = | ||
| 1016 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rxdroppktcnt) + | ||
| 1017 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvovflcnt) + | ||
| 1018 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_portovflcnt) + | ||
| 1019 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errrcvflowctrlcnt) + | ||
| 1020 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_err_rlencnt) + | ||
| 1021 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_invalidrlencnt) + | ||
| 1022 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) + | ||
| 1023 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) + | ||
| 1024 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) + | ||
| 1025 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlinkcnt) + | ||
| 1026 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt); | ||
| 1027 | cntrs->port_rcv_remphys_errors = | ||
| 1028 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt); | ||
| 1029 | cntrs->port_xmit_discards = | ||
| 1030 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_unsupvlcnt); | ||
| 1031 | cntrs->port_xmit_data = | ||
| 1032 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | ||
| 1033 | cntrs->port_rcv_data = | ||
| 1034 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | ||
| 1035 | cntrs->port_xmit_packets = | ||
| 1036 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); | ||
| 1037 | cntrs->port_rcv_packets = | ||
| 1038 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); | ||
| 1039 | |||
| 1040 | ret = 0; | ||
| 1041 | |||
| 1042 | bail: | ||
| 1043 | return ret; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | EXPORT_SYMBOL_GPL(ipath_layer_get_counters); | ||
| 1047 | |||
| 1048 | int ipath_layer_want_buffer(struct ipath_devdata *dd) | ||
| 1049 | { | ||
| 1050 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | ||
| 1051 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 1052 | dd->ipath_sendctrl); | ||
| 1053 | |||
| 1054 | return 0; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | EXPORT_SYMBOL_GPL(ipath_layer_want_buffer); | ||
| 1058 | |||
| 1059 | int ipath_layer_send_hdr(struct ipath_devdata *dd, struct ether_header *hdr) | ||
| 1060 | { | ||
| 1061 | int ret = 0; | ||
| 1062 | u32 __iomem *piobuf; | ||
| 1063 | u32 plen, *uhdr; | ||
| 1064 | size_t count; | ||
| 1065 | __be16 vlsllnh; | ||
| 1066 | |||
| 1067 | if (!(dd->ipath_flags & IPATH_RCVHDRSZ_SET)) { | ||
| 1068 | ipath_dbg("send while not open\n"); | ||
| 1069 | ret = -EINVAL; | ||
| 1070 | } else | ||
| 1071 | if ((dd->ipath_flags & (IPATH_LINKUNK | IPATH_LINKDOWN)) || | ||
| 1072 | dd->ipath_lid == 0) { | ||
| 1073 | /* | ||
| 1074 | * lid check is for when sma hasn't yet configured | ||
| 1075 | */ | ||
| 1076 | ret = -ENETDOWN; | ||
| 1077 | ipath_cdbg(VERBOSE, "send while not ready, " | ||
| 1078 | "mylid=%u, flags=0x%x\n", | ||
| 1079 | dd->ipath_lid, dd->ipath_flags); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | vlsllnh = *((__be16 *) hdr); | ||
| 1083 | if (vlsllnh != htons(IPS_LRH_BTH)) { | ||
| 1084 | ipath_dbg("Warning: lrh[0] wrong (%x, not %x); " | ||
| 1085 | "not sending\n", be16_to_cpu(vlsllnh), | ||
| 1086 | IPS_LRH_BTH); | ||
| 1087 | ret = -EINVAL; | ||
| 1088 | } | ||
| 1089 | if (ret) | ||
| 1090 | goto done; | ||
| 1091 | |||
| 1092 | /* Get a PIO buffer to use. */ | ||
| 1093 | piobuf = ipath_getpiobuf(dd, NULL); | ||
| 1094 | if (piobuf == NULL) { | ||
| 1095 | ret = -EBUSY; | ||
| 1096 | goto done; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | plen = (sizeof(*hdr) >> 2); /* actual length */ | ||
| 1100 | ipath_cdbg(EPKT, "0x%x+1w pio %p\n", plen, piobuf); | ||
| 1101 | |||
| 1102 | writeq(plen+1, piobuf); /* len (+1 for pad) to pbc, no flags */ | ||
| 1103 | ipath_flush_wc(); | ||
| 1104 | piobuf += 2; | ||
| 1105 | uhdr = (u32 *)hdr; | ||
| 1106 | count = plen-1; /* amount we can copy before trigger word */ | ||
| 1107 | __iowrite32_copy(piobuf, uhdr, count); | ||
| 1108 | ipath_flush_wc(); | ||
| 1109 | __raw_writel(uhdr[count], piobuf + count); | ||
| 1110 | ipath_flush_wc(); /* ensure it's sent, now */ | ||
| 1111 | |||
| 1112 | ipath_stats.sps_ether_spkts++; /* ether packet sent */ | ||
| 1113 | |||
| 1114 | done: | ||
| 1115 | return ret; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | EXPORT_SYMBOL_GPL(ipath_layer_send_hdr); | ||
| 1119 | |||
| 1120 | int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd) | ||
| 1121 | { | ||
| 1122 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | ||
| 1123 | |||
| 1124 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 1125 | dd->ipath_sendctrl); | ||
| 1126 | return 0; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | EXPORT_SYMBOL_GPL(ipath_layer_set_piointbufavail_int); | ||
| 1130 | |||
| 1131 | int ipath_layer_enable_timer(struct ipath_devdata *dd) | ||
| 1132 | { | ||
| 1133 | /* | ||
| 1134 | * HT-400 has a design flaw where the chip and kernel idea | ||
| 1135 | * of the tail register don't always agree, and therefore we won't | ||
| 1136 | * get an interrupt on the next packet received. | ||
| 1137 | * If the board supports per packet receive interrupts, use it. | ||
| 1138 | * Otherwise, the timer function periodically checks for packets | ||
| 1139 | * to cover this case. | ||
| 1140 | * Either way, the timer is needed for verbs layer related | ||
| 1141 | * processing. | ||
| 1142 | */ | ||
| 1143 | if (dd->ipath_flags & IPATH_GPIO_INTR) { | ||
| 1144 | ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect, | ||
| 1145 | 0x2074076542310ULL); | ||
| 1146 | /* Enable GPIO bit 2 interrupt */ | ||
| 1147 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, | ||
| 1148 | (u64) (1 << 2)); | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | init_timer(&dd->verbs_layer.l_timer); | ||
| 1152 | dd->verbs_layer.l_timer.function = __ipath_verbs_timer; | ||
| 1153 | dd->verbs_layer.l_timer.data = (unsigned long)dd; | ||
| 1154 | dd->verbs_layer.l_timer.expires = jiffies + 1; | ||
| 1155 | add_timer(&dd->verbs_layer.l_timer); | ||
| 1156 | |||
| 1157 | return 0; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | EXPORT_SYMBOL_GPL(ipath_layer_enable_timer); | ||
| 1161 | |||
| 1162 | int ipath_layer_disable_timer(struct ipath_devdata *dd) | ||
| 1163 | { | ||
| 1164 | /* Disable GPIO bit 2 interrupt */ | ||
| 1165 | if (dd->ipath_flags & IPATH_GPIO_INTR) | ||
| 1166 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, 0); | ||
| 1167 | |||
| 1168 | del_timer_sync(&dd->verbs_layer.l_timer); | ||
| 1169 | |||
| 1170 | return 0; | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | EXPORT_SYMBOL_GPL(ipath_layer_disable_timer); | ||
| 1174 | |||
| 1175 | /** | ||
| 1176 | * ipath_layer_set_verbs_flags - set the verbs layer flags | ||
| 1177 | * @dd: the infinipath device | ||
| 1178 | * @flags: the flags to set | ||
| 1179 | */ | ||
| 1180 | int ipath_layer_set_verbs_flags(struct ipath_devdata *dd, unsigned flags) | ||
| 1181 | { | ||
| 1182 | struct ipath_devdata *ss; | ||
| 1183 | unsigned long lflags; | ||
| 1184 | |||
| 1185 | spin_lock_irqsave(&ipath_devs_lock, lflags); | ||
| 1186 | |||
| 1187 | list_for_each_entry(ss, &ipath_dev_list, ipath_list) { | ||
| 1188 | if (!(ss->ipath_flags & IPATH_INITTED)) | ||
| 1189 | continue; | ||
| 1190 | if ((flags & IPATH_VERBS_KERNEL_SMA) && | ||
| 1191 | !(*ss->ipath_statusp & IPATH_STATUS_SMA)) | ||
| 1192 | *ss->ipath_statusp |= IPATH_STATUS_OIB_SMA; | ||
| 1193 | else | ||
| 1194 | *ss->ipath_statusp &= ~IPATH_STATUS_OIB_SMA; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | spin_unlock_irqrestore(&ipath_devs_lock, lflags); | ||
| 1198 | |||
| 1199 | return 0; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | EXPORT_SYMBOL_GPL(ipath_layer_set_verbs_flags); | ||
| 1203 | |||
| 1204 | /** | ||
| 1205 | * ipath_layer_get_npkeys - return the size of the PKEY table for port 0 | ||
| 1206 | * @dd: the infinipath device | ||
| 1207 | */ | ||
| 1208 | unsigned ipath_layer_get_npkeys(struct ipath_devdata *dd) | ||
| 1209 | { | ||
| 1210 | return ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | EXPORT_SYMBOL_GPL(ipath_layer_get_npkeys); | ||
| 1214 | |||
| 1215 | /** | ||
| 1216 | * ipath_layer_get_pkey - return the indexed PKEY from the port 0 PKEY table | ||
| 1217 | * @dd: the infinipath device | ||
| 1218 | * @index: the PKEY index | ||
| 1219 | */ | ||
| 1220 | unsigned ipath_layer_get_pkey(struct ipath_devdata *dd, unsigned index) | ||
| 1221 | { | ||
| 1222 | unsigned ret; | ||
| 1223 | |||
| 1224 | if (index >= ARRAY_SIZE(dd->ipath_pd[0]->port_pkeys)) | ||
| 1225 | ret = 0; | ||
| 1226 | else | ||
| 1227 | ret = dd->ipath_pd[0]->port_pkeys[index]; | ||
| 1228 | |||
| 1229 | return ret; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | EXPORT_SYMBOL_GPL(ipath_layer_get_pkey); | ||
| 1233 | |||
| 1234 | /** | ||
| 1235 | * ipath_layer_get_pkeys - return the PKEY table for port 0 | ||
| 1236 | * @dd: the infinipath device | ||
| 1237 | * @pkeys: the pkey table is placed here | ||
| 1238 | */ | ||
| 1239 | int ipath_layer_get_pkeys(struct ipath_devdata *dd, u16 * pkeys) | ||
| 1240 | { | ||
| 1241 | struct ipath_portdata *pd = dd->ipath_pd[0]; | ||
| 1242 | |||
| 1243 | memcpy(pkeys, pd->port_pkeys, sizeof(pd->port_pkeys)); | ||
| 1244 | |||
| 1245 | return 0; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | EXPORT_SYMBOL_GPL(ipath_layer_get_pkeys); | ||
| 1249 | |||
| 1250 | /** | ||
| 1251 | * rm_pkey - decrecment the reference count for the given PKEY | ||
| 1252 | * @dd: the infinipath device | ||
| 1253 | * @key: the PKEY index | ||
| 1254 | * | ||
| 1255 | * Return true if this was the last reference and the hardware table entry | ||
| 1256 | * needs to be changed. | ||
| 1257 | */ | ||
| 1258 | static int rm_pkey(struct ipath_devdata *dd, u16 key) | ||
| 1259 | { | ||
| 1260 | int i; | ||
| 1261 | int ret; | ||
| 1262 | |||
| 1263 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
| 1264 | if (dd->ipath_pkeys[i] != key) | ||
| 1265 | continue; | ||
| 1266 | if (atomic_dec_and_test(&dd->ipath_pkeyrefs[i])) { | ||
| 1267 | dd->ipath_pkeys[i] = 0; | ||
| 1268 | ret = 1; | ||
| 1269 | goto bail; | ||
| 1270 | } | ||
| 1271 | break; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | ret = 0; | ||
| 1275 | |||
| 1276 | bail: | ||
| 1277 | return ret; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | /** | ||
| 1281 | * add_pkey - add the given PKEY to the hardware table | ||
| 1282 | * @dd: the infinipath device | ||
| 1283 | * @key: the PKEY | ||
| 1284 | * | ||
| 1285 | * Return an error code if unable to add the entry, zero if no change, | ||
| 1286 | * or 1 if the hardware PKEY register needs to be updated. | ||
| 1287 | */ | ||
| 1288 | static int add_pkey(struct ipath_devdata *dd, u16 key) | ||
| 1289 | { | ||
| 1290 | int i; | ||
| 1291 | u16 lkey = key & 0x7FFF; | ||
| 1292 | int any = 0; | ||
| 1293 | int ret; | ||
| 1294 | |||
| 1295 | if (lkey == 0x7FFF) { | ||
| 1296 | ret = 0; | ||
| 1297 | goto bail; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | /* Look for an empty slot or a matching PKEY. */ | ||
| 1301 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
| 1302 | if (!dd->ipath_pkeys[i]) { | ||
| 1303 | any++; | ||
| 1304 | continue; | ||
| 1305 | } | ||
| 1306 | /* If it matches exactly, try to increment the ref count */ | ||
| 1307 | if (dd->ipath_pkeys[i] == key) { | ||
| 1308 | if (atomic_inc_return(&dd->ipath_pkeyrefs[i]) > 1) { | ||
| 1309 | ret = 0; | ||
| 1310 | goto bail; | ||
| 1311 | } | ||
| 1312 | /* Lost the race. Look for an empty slot below. */ | ||
| 1313 | atomic_dec(&dd->ipath_pkeyrefs[i]); | ||
| 1314 | any++; | ||
| 1315 | } | ||
| 1316 | /* | ||
| 1317 | * It makes no sense to have both the limited and unlimited | ||
| 1318 | * PKEY set at the same time since the unlimited one will | ||
| 1319 | * disable the limited one. | ||
| 1320 | */ | ||
| 1321 | if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) { | ||
| 1322 | ret = -EEXIST; | ||
| 1323 | goto bail; | ||
| 1324 | } | ||
| 1325 | } | ||
| 1326 | if (!any) { | ||
| 1327 | ret = -EBUSY; | ||
| 1328 | goto bail; | ||
| 1329 | } | ||
| 1330 | for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) { | ||
| 1331 | if (!dd->ipath_pkeys[i] && | ||
| 1332 | atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) { | ||
| 1333 | /* for ipathstats, etc. */ | ||
| 1334 | ipath_stats.sps_pkeys[i] = lkey; | ||
| 1335 | dd->ipath_pkeys[i] = key; | ||
| 1336 | ret = 1; | ||
| 1337 | goto bail; | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | ret = -EBUSY; | ||
| 1341 | |||
| 1342 | bail: | ||
| 1343 | return ret; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | /** | ||
| 1347 | * ipath_layer_set_pkeys - set the PKEY table for port 0 | ||
| 1348 | * @dd: the infinipath device | ||
| 1349 | * @pkeys: the PKEY table | ||
| 1350 | */ | ||
| 1351 | int ipath_layer_set_pkeys(struct ipath_devdata *dd, u16 * pkeys) | ||
| 1352 | { | ||
| 1353 | struct ipath_portdata *pd; | ||
| 1354 | int i; | ||
| 1355 | int changed = 0; | ||
| 1356 | |||
| 1357 | pd = dd->ipath_pd[0]; | ||
| 1358 | |||
| 1359 | for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) { | ||
| 1360 | u16 key = pkeys[i]; | ||
| 1361 | u16 okey = pd->port_pkeys[i]; | ||
| 1362 | |||
| 1363 | if (key == okey) | ||
| 1364 | continue; | ||
| 1365 | /* | ||
| 1366 | * The value of this PKEY table entry is changing. | ||
| 1367 | * Remove the old entry in the hardware's array of PKEYs. | ||
| 1368 | */ | ||
| 1369 | if (okey & 0x7FFF) | ||
| 1370 | changed |= rm_pkey(dd, okey); | ||
| 1371 | if (key & 0x7FFF) { | ||
| 1372 | int ret = add_pkey(dd, key); | ||
| 1373 | |||
| 1374 | if (ret < 0) | ||
| 1375 | key = 0; | ||
| 1376 | else | ||
| 1377 | changed |= ret; | ||
| 1378 | } | ||
| 1379 | pd->port_pkeys[i] = key; | ||
| 1380 | } | ||
| 1381 | if (changed) { | ||
| 1382 | u64 pkey; | ||
| 1383 | |||
| 1384 | pkey = (u64) dd->ipath_pkeys[0] | | ||
| 1385 | ((u64) dd->ipath_pkeys[1] << 16) | | ||
| 1386 | ((u64) dd->ipath_pkeys[2] << 32) | | ||
| 1387 | ((u64) dd->ipath_pkeys[3] << 48); | ||
| 1388 | ipath_cdbg(VERBOSE, "p0 new pkey reg %llx\n", | ||
| 1389 | (unsigned long long) pkey); | ||
| 1390 | ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey, | ||
| 1391 | pkey); | ||
| 1392 | } | ||
| 1393 | return 0; | ||
| 1394 | } | ||
| 1395 | |||
| 1396 | EXPORT_SYMBOL_GPL(ipath_layer_set_pkeys); | ||
| 1397 | |||
| 1398 | /** | ||
| 1399 | * ipath_layer_get_linkdowndefaultstate - get the default linkdown state | ||
| 1400 | * @dd: the infinipath device | ||
| 1401 | * | ||
| 1402 | * Returns zero if the default is POLL, 1 if the default is SLEEP. | ||
| 1403 | */ | ||
| 1404 | int ipath_layer_get_linkdowndefaultstate(struct ipath_devdata *dd) | ||
| 1405 | { | ||
| 1406 | return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE); | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | EXPORT_SYMBOL_GPL(ipath_layer_get_linkdowndefaultstate); | ||
| 1410 | |||
| 1411 | /** | ||
| 1412 | * ipath_layer_set_linkdowndefaultstate - set the default linkdown state | ||
| 1413 | * @dd: the infinipath device | ||
| 1414 | * @sleep: the new state | ||
| 1415 | * | ||
| 1416 | * Note that this will only take effect when the link state changes. | ||
| 1417 | */ | ||
| 1418 | int ipath_layer_set_linkdowndefaultstate(struct ipath_devdata *dd, | ||
| 1419 | int sleep) | ||
| 1420 | { | ||
| 1421 | if (sleep) | ||
| 1422 | dd->ipath_ibcctrl |= INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE; | ||
| 1423 | else | ||
| 1424 | dd->ipath_ibcctrl &= ~INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE; | ||
| 1425 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
| 1426 | dd->ipath_ibcctrl); | ||
| 1427 | return 0; | ||
| 1428 | } | ||
| 1429 | |||
| 1430 | EXPORT_SYMBOL_GPL(ipath_layer_set_linkdowndefaultstate); | ||
| 1431 | |||
| 1432 | int ipath_layer_get_phyerrthreshold(struct ipath_devdata *dd) | ||
| 1433 | { | ||
| 1434 | return (dd->ipath_ibcctrl >> | ||
| 1435 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
| 1436 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | EXPORT_SYMBOL_GPL(ipath_layer_get_phyerrthreshold); | ||
| 1440 | |||
| 1441 | /** | ||
| 1442 | * ipath_layer_set_phyerrthreshold - set the physical error threshold | ||
| 1443 | * @dd: the infinipath device | ||
| 1444 | * @n: the new threshold | ||
| 1445 | * | ||
| 1446 | * Note that this will only take effect when the link state changes. | ||
| 1447 | */ | ||
| 1448 | int ipath_layer_set_phyerrthreshold(struct ipath_devdata *dd, unsigned n) | ||
| 1449 | { | ||
| 1450 | unsigned v; | ||
| 1451 | |||
| 1452 | v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
| 1453 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
| 1454 | if (v != n) { | ||
| 1455 | dd->ipath_ibcctrl &= | ||
| 1456 | ~(INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK << | ||
| 1457 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT); | ||
| 1458 | dd->ipath_ibcctrl |= | ||
| 1459 | (u64) n << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT; | ||
| 1460 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
| 1461 | dd->ipath_ibcctrl); | ||
| 1462 | } | ||
| 1463 | return 0; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | EXPORT_SYMBOL_GPL(ipath_layer_set_phyerrthreshold); | ||
| 1467 | |||
| 1468 | int ipath_layer_get_overrunthreshold(struct ipath_devdata *dd) | ||
| 1469 | { | ||
| 1470 | return (dd->ipath_ibcctrl >> | ||
| 1471 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) & | ||
| 1472 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | EXPORT_SYMBOL_GPL(ipath_layer_get_overrunthreshold); | ||
| 1476 | |||
| 1477 | /** | ||
| 1478 | * ipath_layer_set_overrunthreshold - set the overrun threshold | ||
| 1479 | * @dd: the infinipath device | ||
| 1480 | * @n: the new threshold | ||
| 1481 | * | ||
| 1482 | * Note that this will only take effect when the link state changes. | ||
| 1483 | */ | ||
| 1484 | int ipath_layer_set_overrunthreshold(struct ipath_devdata *dd, unsigned n) | ||
| 1485 | { | ||
| 1486 | unsigned v; | ||
| 1487 | |||
| 1488 | v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) & | ||
| 1489 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK; | ||
| 1490 | if (v != n) { | ||
| 1491 | dd->ipath_ibcctrl &= | ||
| 1492 | ~(INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK << | ||
| 1493 | INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT); | ||
| 1494 | dd->ipath_ibcctrl |= | ||
| 1495 | (u64) n << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT; | ||
| 1496 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | ||
| 1497 | dd->ipath_ibcctrl); | ||
| 1498 | } | ||
| 1499 | return 0; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | EXPORT_SYMBOL_GPL(ipath_layer_set_overrunthreshold); | ||
| 1503 | |||
| 1504 | int ipath_layer_get_boardname(struct ipath_devdata *dd, char *name, | ||
| 1505 | size_t namelen) | ||
| 1506 | { | ||
| 1507 | return dd->ipath_f_get_boardname(dd, name, namelen); | ||
| 1508 | } | ||
| 1509 | EXPORT_SYMBOL_GPL(ipath_layer_get_boardname); | ||
| 1510 | |||
| 1511 | u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd) | ||
| 1512 | { | ||
| 1513 | return dd->ipath_rcvhdrentsize; | ||
| 1514 | } | ||
| 1515 | EXPORT_SYMBOL_GPL(ipath_layer_get_rcvhdrentsize); | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.h b/drivers/infiniband/hw/ipath/ipath_layer.h new file mode 100644 index 000000000000..6fefd15bd2da --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_layer.h | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _IPATH_LAYER_H | ||
| 34 | #define _IPATH_LAYER_H | ||
| 35 | |||
| 36 | /* | ||
| 37 | * This header file is for symbols shared between the infinipath driver | ||
| 38 | * and drivers layered upon it (such as ipath). | ||
| 39 | */ | ||
| 40 | |||
| 41 | struct sk_buff; | ||
| 42 | struct ipath_sge_state; | ||
| 43 | struct ipath_devdata; | ||
| 44 | struct ether_header; | ||
| 45 | |||
| 46 | struct ipath_layer_counters { | ||
| 47 | u64 symbol_error_counter; | ||
| 48 | u64 link_error_recovery_counter; | ||
| 49 | u64 link_downed_counter; | ||
| 50 | u64 port_rcv_errors; | ||
| 51 | u64 port_rcv_remphys_errors; | ||
| 52 | u64 port_xmit_discards; | ||
| 53 | u64 port_xmit_data; | ||
| 54 | u64 port_rcv_data; | ||
| 55 | u64 port_xmit_packets; | ||
| 56 | u64 port_rcv_packets; | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* | ||
| 60 | * A segment is a linear region of low physical memory. | ||
| 61 | * XXX Maybe we should use phys addr here and kmap()/kunmap(). | ||
| 62 | * Used by the verbs layer. | ||
| 63 | */ | ||
| 64 | struct ipath_seg { | ||
| 65 | void *vaddr; | ||
| 66 | size_t length; | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* The number of ipath_segs that fit in a page. */ | ||
| 70 | #define IPATH_SEGSZ (PAGE_SIZE / sizeof (struct ipath_seg)) | ||
| 71 | |||
| 72 | struct ipath_segarray { | ||
| 73 | struct ipath_seg segs[IPATH_SEGSZ]; | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct ipath_mregion { | ||
| 77 | u64 user_base; /* User's address for this region */ | ||
| 78 | u64 iova; /* IB start address of this region */ | ||
| 79 | size_t length; | ||
| 80 | u32 lkey; | ||
| 81 | u32 offset; /* offset (bytes) to start of region */ | ||
| 82 | int access_flags; | ||
| 83 | u32 max_segs; /* number of ipath_segs in all the arrays */ | ||
| 84 | u32 mapsz; /* size of the map array */ | ||
| 85 | struct ipath_segarray *map[0]; /* the segments */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | /* | ||
| 89 | * These keep track of the copy progress within a memory region. | ||
| 90 | * Used by the verbs layer. | ||
| 91 | */ | ||
| 92 | struct ipath_sge { | ||
| 93 | struct ipath_mregion *mr; | ||
| 94 | void *vaddr; /* current pointer into the segment */ | ||
| 95 | u32 sge_length; /* length of the SGE */ | ||
| 96 | u32 length; /* remaining length of the segment */ | ||
| 97 | u16 m; /* current index: mr->map[m] */ | ||
| 98 | u16 n; /* current index: mr->map[m]->segs[n] */ | ||
| 99 | }; | ||
| 100 | |||
| 101 | struct ipath_sge_state { | ||
| 102 | struct ipath_sge *sg_list; /* next SGE to be used if any */ | ||
| 103 | struct ipath_sge sge; /* progress state for the current SGE */ | ||
| 104 | u8 num_sge; | ||
| 105 | }; | ||
| 106 | |||
| 107 | int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *), | ||
| 108 | void (*l_remove)(void *), | ||
| 109 | int (*l_intr)(void *, u32), | ||
| 110 | int (*l_rcv)(void *, void *, | ||
| 111 | struct sk_buff *), | ||
| 112 | u16 rcv_opcode, | ||
| 113 | int (*l_rcv_lid)(void *, void *)); | ||
| 114 | int ipath_verbs_register(void *(*l_add)(int, struct ipath_devdata *), | ||
| 115 | void (*l_remove)(void *arg), | ||
| 116 | int (*l_piobufavail)(void *arg), | ||
| 117 | void (*l_rcv)(void *arg, void *rhdr, | ||
| 118 | void *data, u32 tlen), | ||
| 119 | void (*l_timer_cb)(void *arg)); | ||
| 120 | void ipath_layer_unregister(void); | ||
| 121 | void ipath_verbs_unregister(void); | ||
| 122 | int ipath_layer_open(struct ipath_devdata *, u32 * pktmax); | ||
| 123 | u16 ipath_layer_get_lid(struct ipath_devdata *dd); | ||
| 124 | int ipath_layer_get_mac(struct ipath_devdata *dd, u8 *); | ||
| 125 | u16 ipath_layer_get_bcast(struct ipath_devdata *dd); | ||
| 126 | u32 ipath_layer_get_cr_errpkey(struct ipath_devdata *dd); | ||
| 127 | int ipath_layer_set_linkstate(struct ipath_devdata *dd, u8 state); | ||
| 128 | int ipath_layer_set_mtu(struct ipath_devdata *, u16); | ||
| 129 | int ipath_set_sps_lid(struct ipath_devdata *, u32, u8); | ||
| 130 | int ipath_layer_send_hdr(struct ipath_devdata *dd, | ||
| 131 | struct ether_header *hdr); | ||
| 132 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | ||
| 133 | u32 * hdr, u32 len, struct ipath_sge_state *ss); | ||
| 134 | int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd); | ||
| 135 | int ipath_layer_get_boardname(struct ipath_devdata *dd, char *name, | ||
| 136 | size_t namelen); | ||
| 137 | int ipath_layer_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | ||
| 138 | u64 *rwords, u64 *spkts, u64 *rpkts, | ||
| 139 | u64 *xmit_wait); | ||
| 140 | int ipath_layer_get_counters(struct ipath_devdata *dd, | ||
| 141 | struct ipath_layer_counters *cntrs); | ||
| 142 | int ipath_layer_want_buffer(struct ipath_devdata *dd); | ||
| 143 | int ipath_layer_set_guid(struct ipath_devdata *, __be64 guid); | ||
| 144 | __be64 ipath_layer_get_guid(struct ipath_devdata *); | ||
| 145 | u32 ipath_layer_get_nguid(struct ipath_devdata *); | ||
| 146 | int ipath_layer_query_device(struct ipath_devdata *, u32 * vendor, | ||
| 147 | u32 * boardrev, u32 * majrev, u32 * minrev); | ||
| 148 | u32 ipath_layer_get_flags(struct ipath_devdata *dd); | ||
| 149 | struct device *ipath_layer_get_device(struct ipath_devdata *dd); | ||
| 150 | u16 ipath_layer_get_deviceid(struct ipath_devdata *dd); | ||
| 151 | u64 ipath_layer_get_lastibcstat(struct ipath_devdata *dd); | ||
| 152 | u32 ipath_layer_get_ibmtu(struct ipath_devdata *dd); | ||
| 153 | int ipath_layer_enable_timer(struct ipath_devdata *dd); | ||
| 154 | int ipath_layer_disable_timer(struct ipath_devdata *dd); | ||
| 155 | int ipath_layer_set_verbs_flags(struct ipath_devdata *dd, unsigned flags); | ||
| 156 | unsigned ipath_layer_get_npkeys(struct ipath_devdata *dd); | ||
| 157 | unsigned ipath_layer_get_pkey(struct ipath_devdata *dd, unsigned index); | ||
| 158 | int ipath_layer_get_pkeys(struct ipath_devdata *dd, u16 *pkeys); | ||
| 159 | int ipath_layer_set_pkeys(struct ipath_devdata *dd, u16 *pkeys); | ||
| 160 | int ipath_layer_get_linkdowndefaultstate(struct ipath_devdata *dd); | ||
| 161 | int ipath_layer_set_linkdowndefaultstate(struct ipath_devdata *dd, | ||
| 162 | int sleep); | ||
| 163 | int ipath_layer_get_phyerrthreshold(struct ipath_devdata *dd); | ||
| 164 | int ipath_layer_set_phyerrthreshold(struct ipath_devdata *dd, unsigned n); | ||
| 165 | int ipath_layer_get_overrunthreshold(struct ipath_devdata *dd); | ||
| 166 | int ipath_layer_set_overrunthreshold(struct ipath_devdata *dd, unsigned n); | ||
| 167 | u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd); | ||
| 168 | |||
| 169 | /* ipath_ether interrupt values */ | ||
| 170 | #define IPATH_LAYER_INT_IF_UP 0x2 | ||
| 171 | #define IPATH_LAYER_INT_IF_DOWN 0x4 | ||
| 172 | #define IPATH_LAYER_INT_LID 0x8 | ||
| 173 | #define IPATH_LAYER_INT_SEND_CONTINUE 0x10 | ||
| 174 | #define IPATH_LAYER_INT_BCAST 0x40 | ||
| 175 | |||
| 176 | /* _verbs_layer.l_flags */ | ||
| 177 | #define IPATH_VERBS_KERNEL_SMA 0x1 | ||
| 178 | |||
| 179 | extern unsigned ipath_debug; /* debugging bit mask */ | ||
| 180 | |||
| 181 | #endif /* _IPATH_LAYER_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c new file mode 100644 index 000000000000..f7f8391fe43f --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
| @@ -0,0 +1,1352 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <rdma/ib_smi.h> | ||
| 34 | |||
| 35 | #include "ipath_kernel.h" | ||
| 36 | #include "ipath_verbs.h" | ||
| 37 | #include "ips_common.h" | ||
| 38 | |||
| 39 | #define IB_SMP_UNSUP_VERSION __constant_htons(0x0004) | ||
| 40 | #define IB_SMP_UNSUP_METHOD __constant_htons(0x0008) | ||
| 41 | #define IB_SMP_UNSUP_METH_ATTR __constant_htons(0x000C) | ||
| 42 | #define IB_SMP_INVALID_FIELD __constant_htons(0x001C) | ||
| 43 | |||
| 44 | static int reply(struct ib_smp *smp) | ||
| 45 | { | ||
| 46 | /* | ||
| 47 | * The verbs framework will handle the directed/LID route | ||
| 48 | * packet changes. | ||
| 49 | */ | ||
| 50 | smp->method = IB_MGMT_METHOD_GET_RESP; | ||
| 51 | if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) | ||
| 52 | smp->status |= IB_SMP_DIRECTION; | ||
| 53 | return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int recv_subn_get_nodedescription(struct ib_smp *smp, | ||
| 57 | struct ib_device *ibdev) | ||
| 58 | { | ||
| 59 | if (smp->attr_mod) | ||
| 60 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 61 | |||
| 62 | strncpy(smp->data, ibdev->node_desc, sizeof(smp->data)); | ||
| 63 | |||
| 64 | return reply(smp); | ||
| 65 | } | ||
| 66 | |||
| 67 | struct nodeinfo { | ||
| 68 | u8 base_version; | ||
| 69 | u8 class_version; | ||
| 70 | u8 node_type; | ||
| 71 | u8 num_ports; | ||
| 72 | __be64 sys_guid; | ||
| 73 | __be64 node_guid; | ||
| 74 | __be64 port_guid; | ||
| 75 | __be16 partition_cap; | ||
| 76 | __be16 device_id; | ||
| 77 | __be32 revision; | ||
| 78 | u8 local_port_num; | ||
| 79 | u8 vendor_id[3]; | ||
| 80 | } __attribute__ ((packed)); | ||
| 81 | |||
| 82 | static int recv_subn_get_nodeinfo(struct ib_smp *smp, | ||
| 83 | struct ib_device *ibdev, u8 port) | ||
| 84 | { | ||
| 85 | struct nodeinfo *nip = (struct nodeinfo *)&smp->data; | ||
| 86 | struct ipath_devdata *dd = to_idev(ibdev)->dd; | ||
| 87 | u32 vendor, boardid, majrev, minrev; | ||
| 88 | |||
| 89 | if (smp->attr_mod) | ||
| 90 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 91 | |||
| 92 | nip->base_version = 1; | ||
| 93 | nip->class_version = 1; | ||
| 94 | nip->node_type = 1; /* channel adapter */ | ||
| 95 | /* | ||
| 96 | * XXX The num_ports value will need a layer function to get | ||
| 97 | * the value if we ever have more than one IB port on a chip. | ||
| 98 | * We will also need to get the GUID for the port. | ||
| 99 | */ | ||
| 100 | nip->num_ports = ibdev->phys_port_cnt; | ||
| 101 | /* This is already in network order */ | ||
| 102 | nip->sys_guid = to_idev(ibdev)->sys_image_guid; | ||
| 103 | nip->node_guid = ipath_layer_get_guid(dd); | ||
| 104 | nip->port_guid = nip->sys_guid; | ||
| 105 | nip->partition_cap = cpu_to_be16(ipath_layer_get_npkeys(dd)); | ||
| 106 | nip->device_id = cpu_to_be16(ipath_layer_get_deviceid(dd)); | ||
| 107 | ipath_layer_query_device(dd, &vendor, &boardid, &majrev, &minrev); | ||
| 108 | nip->revision = cpu_to_be32((majrev << 16) | minrev); | ||
| 109 | nip->local_port_num = port; | ||
| 110 | nip->vendor_id[0] = 0; | ||
| 111 | nip->vendor_id[1] = vendor >> 8; | ||
| 112 | nip->vendor_id[2] = vendor; | ||
| 113 | |||
| 114 | return reply(smp); | ||
| 115 | } | ||
| 116 | |||
| 117 | static int recv_subn_get_guidinfo(struct ib_smp *smp, | ||
| 118 | struct ib_device *ibdev) | ||
| 119 | { | ||
| 120 | u32 startgx = 8 * be32_to_cpu(smp->attr_mod); | ||
| 121 | __be64 *p = (__be64 *) smp->data; | ||
| 122 | |||
| 123 | /* 32 blocks of 8 64-bit GUIDs per block */ | ||
| 124 | |||
| 125 | memset(smp->data, 0, sizeof(smp->data)); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * We only support one GUID for now. If this changes, the | ||
| 129 | * portinfo.guid_cap field needs to be updated too. | ||
| 130 | */ | ||
| 131 | if (startgx == 0) | ||
| 132 | /* The first is a copy of the read-only HW GUID. */ | ||
| 133 | *p = ipath_layer_get_guid(to_idev(ibdev)->dd); | ||
| 134 | else | ||
| 135 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 136 | |||
| 137 | return reply(smp); | ||
| 138 | } | ||
| 139 | |||
| 140 | struct port_info { | ||
| 141 | __be64 mkey; | ||
| 142 | __be64 gid_prefix; | ||
| 143 | __be16 lid; | ||
| 144 | __be16 sm_lid; | ||
| 145 | __be32 cap_mask; | ||
| 146 | __be16 diag_code; | ||
| 147 | __be16 mkey_lease_period; | ||
| 148 | u8 local_port_num; | ||
| 149 | u8 link_width_enabled; | ||
| 150 | u8 link_width_supported; | ||
| 151 | u8 link_width_active; | ||
| 152 | u8 linkspeed_portstate; /* 4 bits, 4 bits */ | ||
| 153 | u8 portphysstate_linkdown; /* 4 bits, 4 bits */ | ||
| 154 | u8 mkeyprot_resv_lmc; /* 2 bits, 3, 3 */ | ||
| 155 | u8 linkspeedactive_enabled; /* 4 bits, 4 bits */ | ||
| 156 | u8 neighbormtu_mastersmsl; /* 4 bits, 4 bits */ | ||
| 157 | u8 vlcap_inittype; /* 4 bits, 4 bits */ | ||
| 158 | u8 vl_high_limit; | ||
| 159 | u8 vl_arb_high_cap; | ||
| 160 | u8 vl_arb_low_cap; | ||
| 161 | u8 inittypereply_mtucap; /* 4 bits, 4 bits */ | ||
| 162 | u8 vlstallcnt_hoqlife; /* 3 bits, 5 bits */ | ||
| 163 | u8 operationalvl_pei_peo_fpi_fpo; /* 4 bits, 1, 1, 1, 1 */ | ||
| 164 | __be16 mkey_violations; | ||
| 165 | __be16 pkey_violations; | ||
| 166 | __be16 qkey_violations; | ||
| 167 | u8 guid_cap; | ||
| 168 | u8 clientrereg_resv_subnetto; /* 1 bit, 2 bits, 5 */ | ||
| 169 | u8 resv_resptimevalue; /* 3 bits, 5 bits */ | ||
| 170 | u8 localphyerrors_overrunerrors; /* 4 bits, 4 bits */ | ||
| 171 | __be16 max_credit_hint; | ||
| 172 | u8 resv; | ||
| 173 | u8 link_roundtrip_latency[3]; | ||
| 174 | } __attribute__ ((packed)); | ||
| 175 | |||
| 176 | static int recv_subn_get_portinfo(struct ib_smp *smp, | ||
| 177 | struct ib_device *ibdev, u8 port) | ||
| 178 | { | ||
| 179 | struct ipath_ibdev *dev; | ||
| 180 | struct port_info *pip = (struct port_info *)smp->data; | ||
| 181 | u16 lid; | ||
| 182 | u8 ibcstat; | ||
| 183 | u8 mtu; | ||
| 184 | int ret; | ||
| 185 | |||
| 186 | if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) { | ||
| 187 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 188 | ret = reply(smp); | ||
| 189 | goto bail; | ||
| 190 | } | ||
| 191 | |||
| 192 | dev = to_idev(ibdev); | ||
| 193 | |||
| 194 | /* Clear all fields. Only set the non-zero fields. */ | ||
| 195 | memset(smp->data, 0, sizeof(smp->data)); | ||
| 196 | |||
| 197 | /* Only return the mkey if the protection field allows it. */ | ||
| 198 | if (smp->method == IB_MGMT_METHOD_SET || dev->mkey == smp->mkey || | ||
| 199 | (dev->mkeyprot_resv_lmc >> 6) == 0) | ||
| 200 | pip->mkey = dev->mkey; | ||
| 201 | pip->gid_prefix = dev->gid_prefix; | ||
| 202 | lid = ipath_layer_get_lid(dev->dd); | ||
| 203 | pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; | ||
| 204 | pip->sm_lid = cpu_to_be16(dev->sm_lid); | ||
| 205 | pip->cap_mask = cpu_to_be32(dev->port_cap_flags); | ||
| 206 | /* pip->diag_code; */ | ||
| 207 | pip->mkey_lease_period = cpu_to_be16(dev->mkey_lease_period); | ||
| 208 | pip->local_port_num = port; | ||
| 209 | pip->link_width_enabled = dev->link_width_enabled; | ||
| 210 | pip->link_width_supported = 3; /* 1x or 4x */ | ||
| 211 | pip->link_width_active = 2; /* 4x */ | ||
| 212 | pip->linkspeed_portstate = 0x10; /* 2.5Gbps */ | ||
| 213 | ibcstat = ipath_layer_get_lastibcstat(dev->dd); | ||
| 214 | pip->linkspeed_portstate |= ((ibcstat >> 4) & 0x3) + 1; | ||
| 215 | pip->portphysstate_linkdown = | ||
| 216 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | | ||
| 217 | (ipath_layer_get_linkdowndefaultstate(dev->dd) ? 1 : 2); | ||
| 218 | pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc; | ||
| 219 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ | ||
| 220 | switch (ipath_layer_get_ibmtu(dev->dd)) { | ||
| 221 | case 4096: | ||
| 222 | mtu = IB_MTU_4096; | ||
| 223 | break; | ||
| 224 | case 2048: | ||
| 225 | mtu = IB_MTU_2048; | ||
| 226 | break; | ||
| 227 | case 1024: | ||
| 228 | mtu = IB_MTU_1024; | ||
| 229 | break; | ||
| 230 | case 512: | ||
| 231 | mtu = IB_MTU_512; | ||
| 232 | break; | ||
| 233 | case 256: | ||
| 234 | mtu = IB_MTU_256; | ||
| 235 | break; | ||
| 236 | default: /* oops, something is wrong */ | ||
| 237 | mtu = IB_MTU_2048; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | pip->neighbormtu_mastersmsl = (mtu << 4) | dev->sm_sl; | ||
| 241 | pip->vlcap_inittype = 0x10; /* VLCap = VL0, InitType = 0 */ | ||
| 242 | pip->vl_high_limit = dev->vl_high_limit; | ||
| 243 | /* pip->vl_arb_high_cap; // only one VL */ | ||
| 244 | /* pip->vl_arb_low_cap; // only one VL */ | ||
| 245 | /* InitTypeReply = 0 */ | ||
| 246 | pip->inittypereply_mtucap = IB_MTU_4096; | ||
| 247 | // HCAs ignore VLStallCount and HOQLife | ||
| 248 | /* pip->vlstallcnt_hoqlife; */ | ||
| 249 | pip->operationalvl_pei_peo_fpi_fpo = 0x10; /* OVLs = 1 */ | ||
| 250 | pip->mkey_violations = cpu_to_be16(dev->mkey_violations); | ||
| 251 | /* P_KeyViolations are counted by hardware. */ | ||
| 252 | pip->pkey_violations = | ||
| 253 | cpu_to_be16((ipath_layer_get_cr_errpkey(dev->dd) - | ||
| 254 | dev->n_pkey_violations) & 0xFFFF); | ||
| 255 | pip->qkey_violations = cpu_to_be16(dev->qkey_violations); | ||
| 256 | /* Only the hardware GUID is supported for now */ | ||
| 257 | pip->guid_cap = 1; | ||
| 258 | pip->clientrereg_resv_subnetto = dev->subnet_timeout; | ||
| 259 | /* 32.768 usec. response time (guessing) */ | ||
| 260 | pip->resv_resptimevalue = 3; | ||
| 261 | pip->localphyerrors_overrunerrors = | ||
| 262 | (ipath_layer_get_phyerrthreshold(dev->dd) << 4) | | ||
| 263 | ipath_layer_get_overrunthreshold(dev->dd); | ||
| 264 | /* pip->max_credit_hint; */ | ||
| 265 | /* pip->link_roundtrip_latency[3]; */ | ||
| 266 | |||
| 267 | ret = reply(smp); | ||
| 268 | |||
| 269 | bail: | ||
| 270 | return ret; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int recv_subn_get_pkeytable(struct ib_smp *smp, | ||
| 274 | struct ib_device *ibdev) | ||
| 275 | { | ||
| 276 | u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); | ||
| 277 | u16 *p = (u16 *) smp->data; | ||
| 278 | __be16 *q = (__be16 *) smp->data; | ||
| 279 | |||
| 280 | /* 64 blocks of 32 16-bit P_Key entries */ | ||
| 281 | |||
| 282 | memset(smp->data, 0, sizeof(smp->data)); | ||
| 283 | if (startpx == 0) { | ||
| 284 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 285 | unsigned i, n = ipath_layer_get_npkeys(dev->dd); | ||
| 286 | |||
| 287 | ipath_layer_get_pkeys(dev->dd, p); | ||
| 288 | |||
| 289 | for (i = 0; i < n; i++) | ||
| 290 | q[i] = cpu_to_be16(p[i]); | ||
| 291 | } else | ||
| 292 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 293 | |||
| 294 | return reply(smp); | ||
| 295 | } | ||
| 296 | |||
| 297 | static int recv_subn_set_guidinfo(struct ib_smp *smp, | ||
| 298 | struct ib_device *ibdev) | ||
| 299 | { | ||
| 300 | /* The only GUID we support is the first read-only entry. */ | ||
| 301 | return recv_subn_get_guidinfo(smp, ibdev); | ||
| 302 | } | ||
| 303 | |||
| 304 | /** | ||
| 305 | * recv_subn_set_portinfo - set port information | ||
| 306 | * @smp: the incoming SM packet | ||
| 307 | * @ibdev: the infiniband device | ||
| 308 | * @port: the port on the device | ||
| 309 | * | ||
| 310 | * Set Portinfo (see ch. 14.2.5.6). | ||
| 311 | */ | ||
| 312 | static int recv_subn_set_portinfo(struct ib_smp *smp, | ||
| 313 | struct ib_device *ibdev, u8 port) | ||
| 314 | { | ||
| 315 | struct port_info *pip = (struct port_info *)smp->data; | ||
| 316 | struct ib_event event; | ||
| 317 | struct ipath_ibdev *dev; | ||
| 318 | u32 flags; | ||
| 319 | char clientrereg = 0; | ||
| 320 | u16 lid, smlid; | ||
| 321 | u8 lwe; | ||
| 322 | u8 lse; | ||
| 323 | u8 state; | ||
| 324 | u16 lstate; | ||
| 325 | u32 mtu; | ||
| 326 | int ret; | ||
| 327 | |||
| 328 | if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) | ||
| 329 | goto err; | ||
| 330 | |||
| 331 | dev = to_idev(ibdev); | ||
| 332 | event.device = ibdev; | ||
| 333 | event.element.port_num = port; | ||
| 334 | |||
| 335 | dev->mkey = pip->mkey; | ||
| 336 | dev->gid_prefix = pip->gid_prefix; | ||
| 337 | dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); | ||
| 338 | |||
| 339 | lid = be16_to_cpu(pip->lid); | ||
| 340 | if (lid != ipath_layer_get_lid(dev->dd)) { | ||
| 341 | /* Must be a valid unicast LID address. */ | ||
| 342 | if (lid == 0 || lid >= IPS_MULTICAST_LID_BASE) | ||
| 343 | goto err; | ||
| 344 | ipath_set_sps_lid(dev->dd, lid, pip->mkeyprot_resv_lmc & 7); | ||
| 345 | event.event = IB_EVENT_LID_CHANGE; | ||
| 346 | ib_dispatch_event(&event); | ||
| 347 | } | ||
| 348 | |||
| 349 | smlid = be16_to_cpu(pip->sm_lid); | ||
| 350 | if (smlid != dev->sm_lid) { | ||
| 351 | /* Must be a valid unicast LID address. */ | ||
| 352 | if (smlid == 0 || smlid >= IPS_MULTICAST_LID_BASE) | ||
| 353 | goto err; | ||
| 354 | dev->sm_lid = smlid; | ||
| 355 | event.event = IB_EVENT_SM_CHANGE; | ||
| 356 | ib_dispatch_event(&event); | ||
| 357 | } | ||
| 358 | |||
| 359 | /* Only 4x supported but allow 1x or 4x to be set (see 14.2.6.6). */ | ||
| 360 | lwe = pip->link_width_enabled; | ||
| 361 | if ((lwe >= 4 && lwe <= 8) || (lwe >= 0xC && lwe <= 0xFE)) | ||
| 362 | goto err; | ||
| 363 | if (lwe == 0xFF) | ||
| 364 | dev->link_width_enabled = 3; /* 1x or 4x */ | ||
| 365 | else if (lwe) | ||
| 366 | dev->link_width_enabled = lwe; | ||
| 367 | |||
| 368 | /* Only 2.5 Gbs supported. */ | ||
| 369 | lse = pip->linkspeedactive_enabled & 0xF; | ||
| 370 | if (lse >= 2 && lse <= 0xE) | ||
| 371 | goto err; | ||
| 372 | |||
| 373 | /* Set link down default state. */ | ||
| 374 | switch (pip->portphysstate_linkdown & 0xF) { | ||
| 375 | case 0: /* NOP */ | ||
| 376 | break; | ||
| 377 | case 1: /* SLEEP */ | ||
| 378 | if (ipath_layer_set_linkdowndefaultstate(dev->dd, 1)) | ||
| 379 | goto err; | ||
| 380 | break; | ||
| 381 | case 2: /* POLL */ | ||
| 382 | if (ipath_layer_set_linkdowndefaultstate(dev->dd, 0)) | ||
| 383 | goto err; | ||
| 384 | break; | ||
| 385 | default: | ||
| 386 | goto err; | ||
| 387 | } | ||
| 388 | |||
| 389 | dev->mkeyprot_resv_lmc = pip->mkeyprot_resv_lmc; | ||
| 390 | dev->vl_high_limit = pip->vl_high_limit; | ||
| 391 | |||
| 392 | switch ((pip->neighbormtu_mastersmsl >> 4) & 0xF) { | ||
| 393 | case IB_MTU_256: | ||
| 394 | mtu = 256; | ||
| 395 | break; | ||
| 396 | case IB_MTU_512: | ||
| 397 | mtu = 512; | ||
| 398 | break; | ||
| 399 | case IB_MTU_1024: | ||
| 400 | mtu = 1024; | ||
| 401 | break; | ||
| 402 | case IB_MTU_2048: | ||
| 403 | mtu = 2048; | ||
| 404 | break; | ||
| 405 | case IB_MTU_4096: | ||
| 406 | mtu = 4096; | ||
| 407 | break; | ||
| 408 | default: | ||
| 409 | /* XXX We have already partially updated our state! */ | ||
| 410 | goto err; | ||
| 411 | } | ||
| 412 | ipath_layer_set_mtu(dev->dd, mtu); | ||
| 413 | |||
| 414 | dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; | ||
| 415 | |||
| 416 | /* We only support VL0 */ | ||
| 417 | if (((pip->operationalvl_pei_peo_fpi_fpo >> 4) & 0xF) > 1) | ||
| 418 | goto err; | ||
| 419 | |||
| 420 | if (pip->mkey_violations == 0) | ||
| 421 | dev->mkey_violations = 0; | ||
| 422 | |||
| 423 | /* | ||
| 424 | * Hardware counter can't be reset so snapshot and subtract | ||
| 425 | * later. | ||
| 426 | */ | ||
| 427 | if (pip->pkey_violations == 0) | ||
| 428 | dev->n_pkey_violations = | ||
| 429 | ipath_layer_get_cr_errpkey(dev->dd); | ||
| 430 | |||
| 431 | if (pip->qkey_violations == 0) | ||
| 432 | dev->qkey_violations = 0; | ||
| 433 | |||
| 434 | if (ipath_layer_set_phyerrthreshold( | ||
| 435 | dev->dd, | ||
| 436 | (pip->localphyerrors_overrunerrors >> 4) & 0xF)) | ||
| 437 | goto err; | ||
| 438 | |||
| 439 | if (ipath_layer_set_overrunthreshold( | ||
| 440 | dev->dd, | ||
| 441 | (pip->localphyerrors_overrunerrors & 0xF))) | ||
| 442 | goto err; | ||
| 443 | |||
| 444 | dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; | ||
| 445 | |||
| 446 | if (pip->clientrereg_resv_subnetto & 0x80) { | ||
| 447 | clientrereg = 1; | ||
| 448 | event.event = IB_EVENT_LID_CHANGE; | ||
| 449 | ib_dispatch_event(&event); | ||
| 450 | } | ||
| 451 | |||
| 452 | /* | ||
| 453 | * Do the port state change now that the other link parameters | ||
| 454 | * have been set. | ||
| 455 | * Changing the port physical state only makes sense if the link | ||
| 456 | * is down or is being set to down. | ||
| 457 | */ | ||
| 458 | state = pip->linkspeed_portstate & 0xF; | ||
| 459 | flags = ipath_layer_get_flags(dev->dd); | ||
| 460 | lstate = (pip->portphysstate_linkdown >> 4) & 0xF; | ||
| 461 | if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) | ||
| 462 | goto err; | ||
| 463 | |||
| 464 | /* | ||
| 465 | * Only state changes of DOWN, ARM, and ACTIVE are valid | ||
| 466 | * and must be in the correct state to take effect (see 7.2.6). | ||
| 467 | */ | ||
| 468 | switch (state) { | ||
| 469 | case IB_PORT_NOP: | ||
| 470 | if (lstate == 0) | ||
| 471 | break; | ||
| 472 | /* FALLTHROUGH */ | ||
| 473 | case IB_PORT_DOWN: | ||
| 474 | if (lstate == 0) | ||
| 475 | if (ipath_layer_get_linkdowndefaultstate(dev->dd)) | ||
| 476 | lstate = IPATH_IB_LINKDOWN_SLEEP; | ||
| 477 | else | ||
| 478 | lstate = IPATH_IB_LINKDOWN; | ||
| 479 | else if (lstate == 1) | ||
| 480 | lstate = IPATH_IB_LINKDOWN_SLEEP; | ||
| 481 | else if (lstate == 2) | ||
| 482 | lstate = IPATH_IB_LINKDOWN; | ||
| 483 | else if (lstate == 3) | ||
| 484 | lstate = IPATH_IB_LINKDOWN_DISABLE; | ||
| 485 | else | ||
| 486 | goto err; | ||
| 487 | ipath_layer_set_linkstate(dev->dd, lstate); | ||
| 488 | if (flags & IPATH_LINKACTIVE) { | ||
| 489 | event.event = IB_EVENT_PORT_ERR; | ||
| 490 | ib_dispatch_event(&event); | ||
| 491 | } | ||
| 492 | break; | ||
| 493 | case IB_PORT_ARMED: | ||
| 494 | if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE))) | ||
| 495 | break; | ||
| 496 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKARM); | ||
| 497 | if (flags & IPATH_LINKACTIVE) { | ||
| 498 | event.event = IB_EVENT_PORT_ERR; | ||
| 499 | ib_dispatch_event(&event); | ||
| 500 | } | ||
| 501 | break; | ||
| 502 | case IB_PORT_ACTIVE: | ||
| 503 | if (!(flags & IPATH_LINKARMED)) | ||
| 504 | break; | ||
| 505 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE); | ||
| 506 | event.event = IB_EVENT_PORT_ACTIVE; | ||
| 507 | ib_dispatch_event(&event); | ||
| 508 | break; | ||
| 509 | default: | ||
| 510 | /* XXX We have already partially updated our state! */ | ||
| 511 | goto err; | ||
| 512 | } | ||
| 513 | |||
| 514 | ret = recv_subn_get_portinfo(smp, ibdev, port); | ||
| 515 | |||
| 516 | if (clientrereg) | ||
| 517 | pip->clientrereg_resv_subnetto |= 0x80; | ||
| 518 | |||
| 519 | goto done; | ||
| 520 | |||
| 521 | err: | ||
| 522 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 523 | ret = recv_subn_get_portinfo(smp, ibdev, port); | ||
| 524 | |||
| 525 | done: | ||
| 526 | return ret; | ||
| 527 | } | ||
| 528 | |||
| 529 | static int recv_subn_set_pkeytable(struct ib_smp *smp, | ||
| 530 | struct ib_device *ibdev) | ||
| 531 | { | ||
| 532 | u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); | ||
| 533 | __be16 *p = (__be16 *) smp->data; | ||
| 534 | u16 *q = (u16 *) smp->data; | ||
| 535 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 536 | unsigned i, n = ipath_layer_get_npkeys(dev->dd); | ||
| 537 | |||
| 538 | for (i = 0; i < n; i++) | ||
| 539 | q[i] = be16_to_cpu(p[i]); | ||
| 540 | |||
| 541 | if (startpx != 0 || | ||
| 542 | ipath_layer_set_pkeys(dev->dd, q) != 0) | ||
| 543 | smp->status |= IB_SMP_INVALID_FIELD; | ||
| 544 | |||
| 545 | return recv_subn_get_pkeytable(smp, ibdev); | ||
| 546 | } | ||
| 547 | |||
| 548 | #define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001) | ||
| 549 | #define IB_PMA_PORT_SAMPLES_CONTROL __constant_htons(0x0010) | ||
| 550 | #define IB_PMA_PORT_SAMPLES_RESULT __constant_htons(0x0011) | ||
| 551 | #define IB_PMA_PORT_COUNTERS __constant_htons(0x0012) | ||
| 552 | #define IB_PMA_PORT_COUNTERS_EXT __constant_htons(0x001D) | ||
| 553 | #define IB_PMA_PORT_SAMPLES_RESULT_EXT __constant_htons(0x001E) | ||
| 554 | |||
| 555 | struct ib_perf { | ||
| 556 | u8 base_version; | ||
| 557 | u8 mgmt_class; | ||
| 558 | u8 class_version; | ||
| 559 | u8 method; | ||
| 560 | __be16 status; | ||
| 561 | __be16 unused; | ||
| 562 | __be64 tid; | ||
| 563 | __be16 attr_id; | ||
| 564 | __be16 resv; | ||
| 565 | __be32 attr_mod; | ||
| 566 | u8 reserved[40]; | ||
| 567 | u8 data[192]; | ||
| 568 | } __attribute__ ((packed)); | ||
| 569 | |||
| 570 | struct ib_pma_classportinfo { | ||
| 571 | u8 base_version; | ||
| 572 | u8 class_version; | ||
| 573 | __be16 cap_mask; | ||
| 574 | u8 reserved[3]; | ||
| 575 | u8 resp_time_value; /* only lower 5 bits */ | ||
| 576 | union ib_gid redirect_gid; | ||
| 577 | __be32 redirect_tc_sl_fl; /* 8, 4, 20 bits respectively */ | ||
| 578 | __be16 redirect_lid; | ||
| 579 | __be16 redirect_pkey; | ||
| 580 | __be32 redirect_qp; /* only lower 24 bits */ | ||
| 581 | __be32 redirect_qkey; | ||
| 582 | union ib_gid trap_gid; | ||
| 583 | __be32 trap_tc_sl_fl; /* 8, 4, 20 bits respectively */ | ||
| 584 | __be16 trap_lid; | ||
| 585 | __be16 trap_pkey; | ||
| 586 | __be32 trap_hl_qp; /* 8, 24 bits respectively */ | ||
| 587 | __be32 trap_qkey; | ||
| 588 | } __attribute__ ((packed)); | ||
| 589 | |||
| 590 | struct ib_pma_portsamplescontrol { | ||
| 591 | u8 opcode; | ||
| 592 | u8 port_select; | ||
| 593 | u8 tick; | ||
| 594 | u8 counter_width; /* only lower 3 bits */ | ||
| 595 | __be32 counter_mask0_9; /* 2, 10 * 3, bits */ | ||
| 596 | __be16 counter_mask10_14; /* 1, 5 * 3, bits */ | ||
| 597 | u8 sample_mechanisms; | ||
| 598 | u8 sample_status; /* only lower 2 bits */ | ||
| 599 | __be64 option_mask; | ||
| 600 | __be64 vendor_mask; | ||
| 601 | __be32 sample_start; | ||
| 602 | __be32 sample_interval; | ||
| 603 | __be16 tag; | ||
| 604 | __be16 counter_select[15]; | ||
| 605 | } __attribute__ ((packed)); | ||
| 606 | |||
| 607 | struct ib_pma_portsamplesresult { | ||
| 608 | __be16 tag; | ||
| 609 | __be16 sample_status; /* only lower 2 bits */ | ||
| 610 | __be32 counter[15]; | ||
| 611 | } __attribute__ ((packed)); | ||
| 612 | |||
| 613 | struct ib_pma_portsamplesresult_ext { | ||
| 614 | __be16 tag; | ||
| 615 | __be16 sample_status; /* only lower 2 bits */ | ||
| 616 | __be32 extended_width; /* only upper 2 bits */ | ||
| 617 | __be64 counter[15]; | ||
| 618 | } __attribute__ ((packed)); | ||
| 619 | |||
| 620 | struct ib_pma_portcounters { | ||
| 621 | u8 reserved; | ||
| 622 | u8 port_select; | ||
| 623 | __be16 counter_select; | ||
| 624 | __be16 symbol_error_counter; | ||
| 625 | u8 link_error_recovery_counter; | ||
| 626 | u8 link_downed_counter; | ||
| 627 | __be16 port_rcv_errors; | ||
| 628 | __be16 port_rcv_remphys_errors; | ||
| 629 | __be16 port_rcv_switch_relay_errors; | ||
| 630 | __be16 port_xmit_discards; | ||
| 631 | u8 port_xmit_constraint_errors; | ||
| 632 | u8 port_rcv_constraint_errors; | ||
| 633 | u8 reserved1; | ||
| 634 | u8 lli_ebor_errors; /* 4, 4, bits */ | ||
| 635 | __be16 reserved2; | ||
| 636 | __be16 vl15_dropped; | ||
| 637 | __be32 port_xmit_data; | ||
| 638 | __be32 port_rcv_data; | ||
| 639 | __be32 port_xmit_packets; | ||
| 640 | __be32 port_rcv_packets; | ||
| 641 | } __attribute__ ((packed)); | ||
| 642 | |||
| 643 | #define IB_PMA_SEL_SYMBOL_ERROR __constant_htons(0x0001) | ||
| 644 | #define IB_PMA_SEL_LINK_ERROR_RECOVERY __constant_htons(0x0002) | ||
| 645 | #define IB_PMA_SEL_LINK_DOWNED __constant_htons(0x0004) | ||
| 646 | #define IB_PMA_SEL_PORT_RCV_ERRORS __constant_htons(0x0008) | ||
| 647 | #define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS __constant_htons(0x0010) | ||
| 648 | #define IB_PMA_SEL_PORT_XMIT_DISCARDS __constant_htons(0x0040) | ||
| 649 | #define IB_PMA_SEL_PORT_XMIT_DATA __constant_htons(0x1000) | ||
| 650 | #define IB_PMA_SEL_PORT_RCV_DATA __constant_htons(0x2000) | ||
| 651 | #define IB_PMA_SEL_PORT_XMIT_PACKETS __constant_htons(0x4000) | ||
| 652 | #define IB_PMA_SEL_PORT_RCV_PACKETS __constant_htons(0x8000) | ||
| 653 | |||
| 654 | struct ib_pma_portcounters_ext { | ||
| 655 | u8 reserved; | ||
| 656 | u8 port_select; | ||
| 657 | __be16 counter_select; | ||
| 658 | __be32 reserved1; | ||
| 659 | __be64 port_xmit_data; | ||
| 660 | __be64 port_rcv_data; | ||
| 661 | __be64 port_xmit_packets; | ||
| 662 | __be64 port_rcv_packets; | ||
| 663 | __be64 port_unicast_xmit_packets; | ||
| 664 | __be64 port_unicast_rcv_packets; | ||
| 665 | __be64 port_multicast_xmit_packets; | ||
| 666 | __be64 port_multicast_rcv_packets; | ||
| 667 | } __attribute__ ((packed)); | ||
| 668 | |||
| 669 | #define IB_PMA_SELX_PORT_XMIT_DATA __constant_htons(0x0001) | ||
| 670 | #define IB_PMA_SELX_PORT_RCV_DATA __constant_htons(0x0002) | ||
| 671 | #define IB_PMA_SELX_PORT_XMIT_PACKETS __constant_htons(0x0004) | ||
| 672 | #define IB_PMA_SELX_PORT_RCV_PACKETS __constant_htons(0x0008) | ||
| 673 | #define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS __constant_htons(0x0010) | ||
| 674 | #define IB_PMA_SELX_PORT_UNI_RCV_PACKETS __constant_htons(0x0020) | ||
| 675 | #define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS __constant_htons(0x0040) | ||
| 676 | #define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS __constant_htons(0x0080) | ||
| 677 | |||
| 678 | static int recv_pma_get_classportinfo(struct ib_perf *pmp) | ||
| 679 | { | ||
| 680 | struct ib_pma_classportinfo *p = | ||
| 681 | (struct ib_pma_classportinfo *)pmp->data; | ||
| 682 | |||
| 683 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 684 | |||
| 685 | if (pmp->attr_mod != 0) | ||
| 686 | pmp->status |= IB_SMP_INVALID_FIELD; | ||
| 687 | |||
| 688 | /* Indicate AllPortSelect is valid (only one port anyway) */ | ||
| 689 | p->cap_mask = __constant_cpu_to_be16(1 << 8); | ||
| 690 | p->base_version = 1; | ||
| 691 | p->class_version = 1; | ||
| 692 | /* | ||
| 693 | * Expected response time is 4.096 usec. * 2^18 == 1.073741824 | ||
| 694 | * sec. | ||
| 695 | */ | ||
| 696 | p->resp_time_value = 18; | ||
| 697 | |||
| 698 | return reply((struct ib_smp *) pmp); | ||
| 699 | } | ||
| 700 | |||
| 701 | /* | ||
| 702 | * The PortSamplesControl.CounterMasks field is an array of 3 bit fields | ||
| 703 | * which specify the N'th counter's capabilities. See ch. 16.1.3.2. | ||
| 704 | * We support 5 counters which only count the mandatory quantities. | ||
| 705 | */ | ||
| 706 | #define COUNTER_MASK(q, n) (q << ((9 - n) * 3)) | ||
| 707 | #define COUNTER_MASK0_9 \ | ||
| 708 | __constant_cpu_to_be32(COUNTER_MASK(1, 0) | \ | ||
| 709 | COUNTER_MASK(1, 1) | \ | ||
| 710 | COUNTER_MASK(1, 2) | \ | ||
| 711 | COUNTER_MASK(1, 3) | \ | ||
| 712 | COUNTER_MASK(1, 4)) | ||
| 713 | |||
| 714 | static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp, | ||
| 715 | struct ib_device *ibdev, u8 port) | ||
| 716 | { | ||
| 717 | struct ib_pma_portsamplescontrol *p = | ||
| 718 | (struct ib_pma_portsamplescontrol *)pmp->data; | ||
| 719 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 720 | unsigned long flags; | ||
| 721 | u8 port_select = p->port_select; | ||
| 722 | |||
| 723 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 724 | |||
| 725 | p->port_select = port_select; | ||
| 726 | if (pmp->attr_mod != 0 || | ||
| 727 | (port_select != port && port_select != 0xFF)) | ||
| 728 | pmp->status |= IB_SMP_INVALID_FIELD; | ||
| 729 | /* | ||
| 730 | * Ticks are 10x the link transfer period which for 2.5Gbs is 4 | ||
| 731 | * nsec. 0 == 4 nsec., 1 == 8 nsec., ..., 255 == 1020 nsec. Sample | ||
| 732 | * intervals are counted in ticks. Since we use Linux timers, that | ||
| 733 | * count in jiffies, we can't sample for less than 1000 ticks if HZ | ||
| 734 | * == 1000 (4000 ticks if HZ is 250). | ||
| 735 | */ | ||
| 736 | /* XXX This is WRONG. */ | ||
| 737 | p->tick = 250; /* 1 usec. */ | ||
| 738 | p->counter_width = 4; /* 32 bit counters */ | ||
| 739 | p->counter_mask0_9 = COUNTER_MASK0_9; | ||
| 740 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 741 | p->sample_status = dev->pma_sample_status; | ||
| 742 | p->sample_start = cpu_to_be32(dev->pma_sample_start); | ||
| 743 | p->sample_interval = cpu_to_be32(dev->pma_sample_interval); | ||
| 744 | p->tag = cpu_to_be16(dev->pma_tag); | ||
| 745 | p->counter_select[0] = dev->pma_counter_select[0]; | ||
| 746 | p->counter_select[1] = dev->pma_counter_select[1]; | ||
| 747 | p->counter_select[2] = dev->pma_counter_select[2]; | ||
| 748 | p->counter_select[3] = dev->pma_counter_select[3]; | ||
| 749 | p->counter_select[4] = dev->pma_counter_select[4]; | ||
| 750 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 751 | |||
| 752 | return reply((struct ib_smp *) pmp); | ||
| 753 | } | ||
| 754 | |||
| 755 | static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp, | ||
| 756 | struct ib_device *ibdev, u8 port) | ||
| 757 | { | ||
| 758 | struct ib_pma_portsamplescontrol *p = | ||
| 759 | (struct ib_pma_portsamplescontrol *)pmp->data; | ||
| 760 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 761 | unsigned long flags; | ||
| 762 | u32 start; | ||
| 763 | int ret; | ||
| 764 | |||
| 765 | if (pmp->attr_mod != 0 || | ||
| 766 | (p->port_select != port && p->port_select != 0xFF)) { | ||
| 767 | pmp->status |= IB_SMP_INVALID_FIELD; | ||
| 768 | ret = reply((struct ib_smp *) pmp); | ||
| 769 | goto bail; | ||
| 770 | } | ||
| 771 | |||
| 772 | start = be32_to_cpu(p->sample_start); | ||
| 773 | if (start != 0) { | ||
| 774 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 775 | if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_DONE) { | ||
| 776 | dev->pma_sample_status = | ||
| 777 | IB_PMA_SAMPLE_STATUS_STARTED; | ||
| 778 | dev->pma_sample_start = start; | ||
| 779 | dev->pma_sample_interval = | ||
| 780 | be32_to_cpu(p->sample_interval); | ||
| 781 | dev->pma_tag = be16_to_cpu(p->tag); | ||
| 782 | if (p->counter_select[0]) | ||
| 783 | dev->pma_counter_select[0] = | ||
| 784 | p->counter_select[0]; | ||
| 785 | if (p->counter_select[1]) | ||
| 786 | dev->pma_counter_select[1] = | ||
| 787 | p->counter_select[1]; | ||
| 788 | if (p->counter_select[2]) | ||
| 789 | dev->pma_counter_select[2] = | ||
| 790 | p->counter_select[2]; | ||
| 791 | if (p->counter_select[3]) | ||
| 792 | dev->pma_counter_select[3] = | ||
| 793 | p->counter_select[3]; | ||
| 794 | if (p->counter_select[4]) | ||
| 795 | dev->pma_counter_select[4] = | ||
| 796 | p->counter_select[4]; | ||
| 797 | } | ||
| 798 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 799 | } | ||
| 800 | ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port); | ||
| 801 | |||
| 802 | bail: | ||
| 803 | return ret; | ||
| 804 | } | ||
| 805 | |||
| 806 | static u64 get_counter(struct ipath_ibdev *dev, __be16 sel) | ||
| 807 | { | ||
| 808 | u64 ret; | ||
| 809 | |||
| 810 | switch (sel) { | ||
| 811 | case IB_PMA_PORT_XMIT_DATA: | ||
| 812 | ret = dev->ipath_sword; | ||
| 813 | break; | ||
| 814 | case IB_PMA_PORT_RCV_DATA: | ||
| 815 | ret = dev->ipath_rword; | ||
| 816 | break; | ||
| 817 | case IB_PMA_PORT_XMIT_PKTS: | ||
| 818 | ret = dev->ipath_spkts; | ||
| 819 | break; | ||
| 820 | case IB_PMA_PORT_RCV_PKTS: | ||
| 821 | ret = dev->ipath_rpkts; | ||
| 822 | break; | ||
| 823 | case IB_PMA_PORT_XMIT_WAIT: | ||
| 824 | ret = dev->ipath_xmit_wait; | ||
| 825 | break; | ||
| 826 | default: | ||
| 827 | ret = 0; | ||
| 828 | } | ||
| 829 | |||
| 830 | return ret; | ||
| 831 | } | ||
| 832 | |||
| 833 | static int recv_pma_get_portsamplesresult(struct ib_perf *pmp, | ||
| 834 | struct ib_device *ibdev) | ||
| 835 | { | ||
| 836 | struct ib_pma_portsamplesresult *p = | ||
| 837 | (struct ib_pma_portsamplesresult *)pmp->data; | ||
| 838 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 839 | int i; | ||
| 840 | |||
| 841 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 842 | p->tag = cpu_to_be16(dev->pma_tag); | ||
| 843 | p->sample_status = cpu_to_be16(dev->pma_sample_status); | ||
| 844 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) | ||
| 845 | p->counter[i] = cpu_to_be32( | ||
| 846 | get_counter(dev, dev->pma_counter_select[i])); | ||
| 847 | |||
| 848 | return reply((struct ib_smp *) pmp); | ||
| 849 | } | ||
| 850 | |||
| 851 | static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp, | ||
| 852 | struct ib_device *ibdev) | ||
| 853 | { | ||
| 854 | struct ib_pma_portsamplesresult_ext *p = | ||
| 855 | (struct ib_pma_portsamplesresult_ext *)pmp->data; | ||
| 856 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 857 | int i; | ||
| 858 | |||
| 859 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 860 | p->tag = cpu_to_be16(dev->pma_tag); | ||
| 861 | p->sample_status = cpu_to_be16(dev->pma_sample_status); | ||
| 862 | /* 64 bits */ | ||
| 863 | p->extended_width = __constant_cpu_to_be32(0x80000000); | ||
| 864 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) | ||
| 865 | p->counter[i] = cpu_to_be64( | ||
| 866 | get_counter(dev, dev->pma_counter_select[i])); | ||
| 867 | |||
| 868 | return reply((struct ib_smp *) pmp); | ||
| 869 | } | ||
| 870 | |||
| 871 | static int recv_pma_get_portcounters(struct ib_perf *pmp, | ||
| 872 | struct ib_device *ibdev, u8 port) | ||
| 873 | { | ||
| 874 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) | ||
| 875 | pmp->data; | ||
| 876 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 877 | struct ipath_layer_counters cntrs; | ||
| 878 | u8 port_select = p->port_select; | ||
| 879 | |||
| 880 | ipath_layer_get_counters(dev->dd, &cntrs); | ||
| 881 | |||
| 882 | /* Adjust counters for any resets done. */ | ||
| 883 | cntrs.symbol_error_counter -= dev->n_symbol_error_counter; | ||
| 884 | cntrs.link_error_recovery_counter -= | ||
| 885 | dev->n_link_error_recovery_counter; | ||
| 886 | cntrs.link_downed_counter -= dev->n_link_downed_counter; | ||
| 887 | cntrs.port_rcv_errors += dev->rcv_errors; | ||
| 888 | cntrs.port_rcv_errors -= dev->n_port_rcv_errors; | ||
| 889 | cntrs.port_rcv_remphys_errors -= dev->n_port_rcv_remphys_errors; | ||
| 890 | cntrs.port_xmit_discards -= dev->n_port_xmit_discards; | ||
| 891 | cntrs.port_xmit_data -= dev->n_port_xmit_data; | ||
| 892 | cntrs.port_rcv_data -= dev->n_port_rcv_data; | ||
| 893 | cntrs.port_xmit_packets -= dev->n_port_xmit_packets; | ||
| 894 | cntrs.port_rcv_packets -= dev->n_port_rcv_packets; | ||
| 895 | |||
| 896 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 897 | |||
| 898 | p->port_select = port_select; | ||
| 899 | if (pmp->attr_mod != 0 || | ||
| 900 | (port_select != port && port_select != 0xFF)) | ||
| 901 | pmp->status |= IB_SMP_INVALID_FIELD; | ||
| 902 | |||
| 903 | if (cntrs.symbol_error_counter > 0xFFFFUL) | ||
| 904 | p->symbol_error_counter = __constant_cpu_to_be16(0xFFFF); | ||
| 905 | else | ||
| 906 | p->symbol_error_counter = | ||
| 907 | cpu_to_be16((u16)cntrs.symbol_error_counter); | ||
| 908 | if (cntrs.link_error_recovery_counter > 0xFFUL) | ||
| 909 | p->link_error_recovery_counter = 0xFF; | ||
| 910 | else | ||
| 911 | p->link_error_recovery_counter = | ||
| 912 | (u8)cntrs.link_error_recovery_counter; | ||
| 913 | if (cntrs.link_downed_counter > 0xFFUL) | ||
| 914 | p->link_downed_counter = 0xFF; | ||
| 915 | else | ||
| 916 | p->link_downed_counter = (u8)cntrs.link_downed_counter; | ||
| 917 | if (cntrs.port_rcv_errors > 0xFFFFUL) | ||
| 918 | p->port_rcv_errors = __constant_cpu_to_be16(0xFFFF); | ||
| 919 | else | ||
| 920 | p->port_rcv_errors = | ||
| 921 | cpu_to_be16((u16) cntrs.port_rcv_errors); | ||
| 922 | if (cntrs.port_rcv_remphys_errors > 0xFFFFUL) | ||
| 923 | p->port_rcv_remphys_errors = __constant_cpu_to_be16(0xFFFF); | ||
| 924 | else | ||
| 925 | p->port_rcv_remphys_errors = | ||
| 926 | cpu_to_be16((u16)cntrs.port_rcv_remphys_errors); | ||
| 927 | if (cntrs.port_xmit_discards > 0xFFFFUL) | ||
| 928 | p->port_xmit_discards = __constant_cpu_to_be16(0xFFFF); | ||
| 929 | else | ||
| 930 | p->port_xmit_discards = | ||
| 931 | cpu_to_be16((u16)cntrs.port_xmit_discards); | ||
| 932 | if (cntrs.port_xmit_data > 0xFFFFFFFFUL) | ||
| 933 | p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF); | ||
| 934 | else | ||
| 935 | p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data); | ||
| 936 | if (cntrs.port_rcv_data > 0xFFFFFFFFUL) | ||
| 937 | p->port_rcv_data = __constant_cpu_to_be32(0xFFFFFFFF); | ||
| 938 | else | ||
| 939 | p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data); | ||
| 940 | if (cntrs.port_xmit_packets > 0xFFFFFFFFUL) | ||
| 941 | p->port_xmit_packets = __constant_cpu_to_be32(0xFFFFFFFF); | ||
| 942 | else | ||
| 943 | p->port_xmit_packets = | ||
| 944 | cpu_to_be32((u32)cntrs.port_xmit_packets); | ||
| 945 | if (cntrs.port_rcv_packets > 0xFFFFFFFFUL) | ||
| 946 | p->port_rcv_packets = __constant_cpu_to_be32(0xFFFFFFFF); | ||
| 947 | else | ||
| 948 | p->port_rcv_packets = | ||
| 949 | cpu_to_be32((u32) cntrs.port_rcv_packets); | ||
| 950 | |||
| 951 | return reply((struct ib_smp *) pmp); | ||
| 952 | } | ||
| 953 | |||
| 954 | static int recv_pma_get_portcounters_ext(struct ib_perf *pmp, | ||
| 955 | struct ib_device *ibdev, u8 port) | ||
| 956 | { | ||
| 957 | struct ib_pma_portcounters_ext *p = | ||
| 958 | (struct ib_pma_portcounters_ext *)pmp->data; | ||
| 959 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 960 | u64 swords, rwords, spkts, rpkts, xwait; | ||
| 961 | u8 port_select = p->port_select; | ||
| 962 | |||
| 963 | ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, | ||
| 964 | &rpkts, &xwait); | ||
| 965 | |||
| 966 | /* Adjust counters for any resets done. */ | ||
| 967 | swords -= dev->n_port_xmit_data; | ||
| 968 | rwords -= dev->n_port_rcv_data; | ||
| 969 | spkts -= dev->n_port_xmit_packets; | ||
| 970 | rpkts -= dev->n_port_rcv_packets; | ||
| 971 | |||
| 972 | memset(pmp->data, 0, sizeof(pmp->data)); | ||
| 973 | |||
| 974 | p->port_select = port_select; | ||
| 975 | if (pmp->attr_mod != 0 || | ||
| 976 | (port_select != port && port_select != 0xFF)) | ||
| 977 | pmp->status |= IB_SMP_INVALID_FIELD; | ||
| 978 | |||
| 979 | p->port_xmit_data = cpu_to_be64(swords); | ||
| 980 | p->port_rcv_data = cpu_to_be64(rwords); | ||
| 981 | p->port_xmit_packets = cpu_to_be64(spkts); | ||
| 982 | p->port_rcv_packets = cpu_to_be64(rpkts); | ||
| 983 | p->port_unicast_xmit_packets = cpu_to_be64(dev->n_unicast_xmit); | ||
| 984 | p->port_unicast_rcv_packets = cpu_to_be64(dev->n_unicast_rcv); | ||
| 985 | p->port_multicast_xmit_packets = cpu_to_be64(dev->n_multicast_xmit); | ||
| 986 | p->port_multicast_rcv_packets = cpu_to_be64(dev->n_multicast_rcv); | ||
| 987 | |||
| 988 | return reply((struct ib_smp *) pmp); | ||
| 989 | } | ||
| 990 | |||
| 991 | static int recv_pma_set_portcounters(struct ib_perf *pmp, | ||
| 992 | struct ib_device *ibdev, u8 port) | ||
| 993 | { | ||
| 994 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) | ||
| 995 | pmp->data; | ||
| 996 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 997 | struct ipath_layer_counters cntrs; | ||
| 998 | |||
| 999 | /* | ||
| 1000 | * Since the HW doesn't support clearing counters, we save the | ||
| 1001 | * current count and subtract it from future responses. | ||
| 1002 | */ | ||
| 1003 | ipath_layer_get_counters(dev->dd, &cntrs); | ||
| 1004 | |||
| 1005 | if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) | ||
| 1006 | dev->n_symbol_error_counter = cntrs.symbol_error_counter; | ||
| 1007 | |||
| 1008 | if (p->counter_select & IB_PMA_SEL_LINK_ERROR_RECOVERY) | ||
| 1009 | dev->n_link_error_recovery_counter = | ||
| 1010 | cntrs.link_error_recovery_counter; | ||
| 1011 | |||
| 1012 | if (p->counter_select & IB_PMA_SEL_LINK_DOWNED) | ||
| 1013 | dev->n_link_downed_counter = cntrs.link_downed_counter; | ||
| 1014 | |||
| 1015 | if (p->counter_select & IB_PMA_SEL_PORT_RCV_ERRORS) | ||
| 1016 | dev->n_port_rcv_errors = | ||
| 1017 | cntrs.port_rcv_errors + dev->rcv_errors; | ||
| 1018 | |||
| 1019 | if (p->counter_select & IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS) | ||
| 1020 | dev->n_port_rcv_remphys_errors = | ||
| 1021 | cntrs.port_rcv_remphys_errors; | ||
| 1022 | |||
| 1023 | if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DISCARDS) | ||
| 1024 | dev->n_port_xmit_discards = cntrs.port_xmit_discards; | ||
| 1025 | |||
| 1026 | if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) | ||
| 1027 | dev->n_port_xmit_data = cntrs.port_xmit_data; | ||
| 1028 | |||
| 1029 | if (p->counter_select & IB_PMA_SEL_PORT_RCV_DATA) | ||
| 1030 | dev->n_port_rcv_data = cntrs.port_rcv_data; | ||
| 1031 | |||
| 1032 | if (p->counter_select & IB_PMA_SEL_PORT_XMIT_PACKETS) | ||
| 1033 | dev->n_port_xmit_packets = cntrs.port_xmit_packets; | ||
| 1034 | |||
| 1035 | if (p->counter_select & IB_PMA_SEL_PORT_RCV_PACKETS) | ||
| 1036 | dev->n_port_rcv_packets = cntrs.port_rcv_packets; | ||
| 1037 | |||
| 1038 | return recv_pma_get_portcounters(pmp, ibdev, port); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | static int recv_pma_set_portcounters_ext(struct ib_perf *pmp, | ||
| 1042 | struct ib_device *ibdev, u8 port) | ||
| 1043 | { | ||
| 1044 | struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) | ||
| 1045 | pmp->data; | ||
| 1046 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 1047 | u64 swords, rwords, spkts, rpkts, xwait; | ||
| 1048 | |||
| 1049 | ipath_layer_snapshot_counters(dev->dd, &swords, &rwords, &spkts, | ||
| 1050 | &rpkts, &xwait); | ||
| 1051 | |||
| 1052 | if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) | ||
| 1053 | dev->n_port_xmit_data = swords; | ||
| 1054 | |||
| 1055 | if (p->counter_select & IB_PMA_SELX_PORT_RCV_DATA) | ||
| 1056 | dev->n_port_rcv_data = rwords; | ||
| 1057 | |||
| 1058 | if (p->counter_select & IB_PMA_SELX_PORT_XMIT_PACKETS) | ||
| 1059 | dev->n_port_xmit_packets = spkts; | ||
| 1060 | |||
| 1061 | if (p->counter_select & IB_PMA_SELX_PORT_RCV_PACKETS) | ||
| 1062 | dev->n_port_rcv_packets = rpkts; | ||
| 1063 | |||
| 1064 | if (p->counter_select & IB_PMA_SELX_PORT_UNI_XMIT_PACKETS) | ||
| 1065 | dev->n_unicast_xmit = 0; | ||
| 1066 | |||
| 1067 | if (p->counter_select & IB_PMA_SELX_PORT_UNI_RCV_PACKETS) | ||
| 1068 | dev->n_unicast_rcv = 0; | ||
| 1069 | |||
| 1070 | if (p->counter_select & IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS) | ||
| 1071 | dev->n_multicast_xmit = 0; | ||
| 1072 | |||
| 1073 | if (p->counter_select & IB_PMA_SELX_PORT_MULTI_RCV_PACKETS) | ||
| 1074 | dev->n_multicast_rcv = 0; | ||
| 1075 | |||
| 1076 | return recv_pma_get_portcounters_ext(pmp, ibdev, port); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static int process_subn(struct ib_device *ibdev, int mad_flags, | ||
| 1080 | u8 port_num, struct ib_mad *in_mad, | ||
| 1081 | struct ib_mad *out_mad) | ||
| 1082 | { | ||
| 1083 | struct ib_smp *smp = (struct ib_smp *)out_mad; | ||
| 1084 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 1085 | int ret; | ||
| 1086 | |||
| 1087 | *out_mad = *in_mad; | ||
| 1088 | if (smp->class_version != 1) { | ||
| 1089 | smp->status |= IB_SMP_UNSUP_VERSION; | ||
| 1090 | ret = reply(smp); | ||
| 1091 | goto bail; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* Is the mkey in the process of expiring? */ | ||
| 1095 | if (dev->mkey_lease_timeout && jiffies >= dev->mkey_lease_timeout) { | ||
| 1096 | /* Clear timeout and mkey protection field. */ | ||
| 1097 | dev->mkey_lease_timeout = 0; | ||
| 1098 | dev->mkeyprot_resv_lmc &= 0x3F; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | /* | ||
| 1102 | * M_Key checking depends on | ||
| 1103 | * Portinfo:M_Key_protect_bits | ||
| 1104 | */ | ||
| 1105 | if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && dev->mkey != 0 && | ||
| 1106 | dev->mkey != smp->mkey && | ||
| 1107 | (smp->method == IB_MGMT_METHOD_SET || | ||
| 1108 | (smp->method == IB_MGMT_METHOD_GET && | ||
| 1109 | (dev->mkeyprot_resv_lmc >> 7) != 0))) { | ||
| 1110 | if (dev->mkey_violations != 0xFFFF) | ||
| 1111 | ++dev->mkey_violations; | ||
| 1112 | if (dev->mkey_lease_timeout || | ||
| 1113 | dev->mkey_lease_period == 0) { | ||
| 1114 | ret = IB_MAD_RESULT_SUCCESS | | ||
| 1115 | IB_MAD_RESULT_CONSUMED; | ||
| 1116 | goto bail; | ||
| 1117 | } | ||
| 1118 | dev->mkey_lease_timeout = jiffies + | ||
| 1119 | dev->mkey_lease_period * HZ; | ||
| 1120 | /* Future: Generate a trap notice. */ | ||
| 1121 | ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; | ||
| 1122 | goto bail; | ||
| 1123 | } else if (dev->mkey_lease_timeout) | ||
| 1124 | dev->mkey_lease_timeout = 0; | ||
| 1125 | |||
| 1126 | switch (smp->method) { | ||
| 1127 | case IB_MGMT_METHOD_GET: | ||
| 1128 | switch (smp->attr_id) { | ||
| 1129 | case IB_SMP_ATTR_NODE_DESC: | ||
| 1130 | ret = recv_subn_get_nodedescription(smp, ibdev); | ||
| 1131 | goto bail; | ||
| 1132 | case IB_SMP_ATTR_NODE_INFO: | ||
| 1133 | ret = recv_subn_get_nodeinfo(smp, ibdev, port_num); | ||
| 1134 | goto bail; | ||
| 1135 | case IB_SMP_ATTR_GUID_INFO: | ||
| 1136 | ret = recv_subn_get_guidinfo(smp, ibdev); | ||
| 1137 | goto bail; | ||
| 1138 | case IB_SMP_ATTR_PORT_INFO: | ||
| 1139 | ret = recv_subn_get_portinfo(smp, ibdev, port_num); | ||
| 1140 | goto bail; | ||
| 1141 | case IB_SMP_ATTR_PKEY_TABLE: | ||
| 1142 | ret = recv_subn_get_pkeytable(smp, ibdev); | ||
| 1143 | goto bail; | ||
| 1144 | case IB_SMP_ATTR_SM_INFO: | ||
| 1145 | if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { | ||
| 1146 | ret = IB_MAD_RESULT_SUCCESS | | ||
| 1147 | IB_MAD_RESULT_CONSUMED; | ||
| 1148 | goto bail; | ||
| 1149 | } | ||
| 1150 | if (dev->port_cap_flags & IB_PORT_SM) { | ||
| 1151 | ret = IB_MAD_RESULT_SUCCESS; | ||
| 1152 | goto bail; | ||
| 1153 | } | ||
| 1154 | /* FALLTHROUGH */ | ||
| 1155 | default: | ||
| 1156 | smp->status |= IB_SMP_UNSUP_METH_ATTR; | ||
| 1157 | ret = reply(smp); | ||
| 1158 | goto bail; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | case IB_MGMT_METHOD_SET: | ||
| 1162 | switch (smp->attr_id) { | ||
| 1163 | case IB_SMP_ATTR_GUID_INFO: | ||
| 1164 | ret = recv_subn_set_guidinfo(smp, ibdev); | ||
| 1165 | goto bail; | ||
| 1166 | case IB_SMP_ATTR_PORT_INFO: | ||
| 1167 | ret = recv_subn_set_portinfo(smp, ibdev, port_num); | ||
| 1168 | goto bail; | ||
| 1169 | case IB_SMP_ATTR_PKEY_TABLE: | ||
| 1170 | ret = recv_subn_set_pkeytable(smp, ibdev); | ||
| 1171 | goto bail; | ||
| 1172 | case IB_SMP_ATTR_SM_INFO: | ||
| 1173 | if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { | ||
| 1174 | ret = IB_MAD_RESULT_SUCCESS | | ||
| 1175 | IB_MAD_RESULT_CONSUMED; | ||
| 1176 | goto bail; | ||
| 1177 | } | ||
| 1178 | if (dev->port_cap_flags & IB_PORT_SM) { | ||
| 1179 | ret = IB_MAD_RESULT_SUCCESS; | ||
| 1180 | goto bail; | ||
| 1181 | } | ||
| 1182 | /* FALLTHROUGH */ | ||
| 1183 | default: | ||
| 1184 | smp->status |= IB_SMP_UNSUP_METH_ATTR; | ||
| 1185 | ret = reply(smp); | ||
| 1186 | goto bail; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | case IB_MGMT_METHOD_GET_RESP: | ||
| 1190 | /* | ||
| 1191 | * The ib_mad module will call us to process responses | ||
| 1192 | * before checking for other consumers. | ||
| 1193 | * Just tell the caller to process it normally. | ||
| 1194 | */ | ||
| 1195 | ret = IB_MAD_RESULT_FAILURE; | ||
| 1196 | goto bail; | ||
| 1197 | default: | ||
| 1198 | smp->status |= IB_SMP_UNSUP_METHOD; | ||
| 1199 | ret = reply(smp); | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | bail: | ||
| 1203 | return ret; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | static int process_perf(struct ib_device *ibdev, u8 port_num, | ||
| 1207 | struct ib_mad *in_mad, | ||
| 1208 | struct ib_mad *out_mad) | ||
| 1209 | { | ||
| 1210 | struct ib_perf *pmp = (struct ib_perf *)out_mad; | ||
| 1211 | int ret; | ||
| 1212 | |||
| 1213 | *out_mad = *in_mad; | ||
| 1214 | if (pmp->class_version != 1) { | ||
| 1215 | pmp->status |= IB_SMP_UNSUP_VERSION; | ||
| 1216 | ret = reply((struct ib_smp *) pmp); | ||
| 1217 | goto bail; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | switch (pmp->method) { | ||
| 1221 | case IB_MGMT_METHOD_GET: | ||
| 1222 | switch (pmp->attr_id) { | ||
| 1223 | case IB_PMA_CLASS_PORT_INFO: | ||
| 1224 | ret = recv_pma_get_classportinfo(pmp); | ||
| 1225 | goto bail; | ||
| 1226 | case IB_PMA_PORT_SAMPLES_CONTROL: | ||
| 1227 | ret = recv_pma_get_portsamplescontrol(pmp, ibdev, | ||
| 1228 | port_num); | ||
| 1229 | goto bail; | ||
| 1230 | case IB_PMA_PORT_SAMPLES_RESULT: | ||
| 1231 | ret = recv_pma_get_portsamplesresult(pmp, ibdev); | ||
| 1232 | goto bail; | ||
| 1233 | case IB_PMA_PORT_SAMPLES_RESULT_EXT: | ||
| 1234 | ret = recv_pma_get_portsamplesresult_ext(pmp, | ||
| 1235 | ibdev); | ||
| 1236 | goto bail; | ||
| 1237 | case IB_PMA_PORT_COUNTERS: | ||
| 1238 | ret = recv_pma_get_portcounters(pmp, ibdev, | ||
| 1239 | port_num); | ||
| 1240 | goto bail; | ||
| 1241 | case IB_PMA_PORT_COUNTERS_EXT: | ||
| 1242 | ret = recv_pma_get_portcounters_ext(pmp, ibdev, | ||
| 1243 | port_num); | ||
| 1244 | goto bail; | ||
| 1245 | default: | ||
| 1246 | pmp->status |= IB_SMP_UNSUP_METH_ATTR; | ||
| 1247 | ret = reply((struct ib_smp *) pmp); | ||
| 1248 | goto bail; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | case IB_MGMT_METHOD_SET: | ||
| 1252 | switch (pmp->attr_id) { | ||
| 1253 | case IB_PMA_PORT_SAMPLES_CONTROL: | ||
| 1254 | ret = recv_pma_set_portsamplescontrol(pmp, ibdev, | ||
| 1255 | port_num); | ||
| 1256 | goto bail; | ||
| 1257 | case IB_PMA_PORT_COUNTERS: | ||
| 1258 | ret = recv_pma_set_portcounters(pmp, ibdev, | ||
| 1259 | port_num); | ||
| 1260 | goto bail; | ||
| 1261 | case IB_PMA_PORT_COUNTERS_EXT: | ||
| 1262 | ret = recv_pma_set_portcounters_ext(pmp, ibdev, | ||
| 1263 | port_num); | ||
| 1264 | goto bail; | ||
| 1265 | default: | ||
| 1266 | pmp->status |= IB_SMP_UNSUP_METH_ATTR; | ||
| 1267 | ret = reply((struct ib_smp *) pmp); | ||
| 1268 | goto bail; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | case IB_MGMT_METHOD_GET_RESP: | ||
| 1272 | /* | ||
| 1273 | * The ib_mad module will call us to process responses | ||
| 1274 | * before checking for other consumers. | ||
| 1275 | * Just tell the caller to process it normally. | ||
| 1276 | */ | ||
| 1277 | ret = IB_MAD_RESULT_FAILURE; | ||
| 1278 | goto bail; | ||
| 1279 | default: | ||
| 1280 | pmp->status |= IB_SMP_UNSUP_METHOD; | ||
| 1281 | ret = reply((struct ib_smp *) pmp); | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | bail: | ||
| 1285 | return ret; | ||
| 1286 | } | ||
| 1287 | |||
| 1288 | /** | ||
| 1289 | * ipath_process_mad - process an incoming MAD packet | ||
| 1290 | * @ibdev: the infiniband device this packet came in on | ||
| 1291 | * @mad_flags: MAD flags | ||
| 1292 | * @port_num: the port number this packet came in on | ||
| 1293 | * @in_wc: the work completion entry for this packet | ||
| 1294 | * @in_grh: the global route header for this packet | ||
| 1295 | * @in_mad: the incoming MAD | ||
| 1296 | * @out_mad: any outgoing MAD reply | ||
| 1297 | * | ||
| 1298 | * Returns IB_MAD_RESULT_SUCCESS if this is a MAD that we are not | ||
| 1299 | * interested in processing. | ||
| 1300 | * | ||
| 1301 | * Note that the verbs framework has already done the MAD sanity checks, | ||
| 1302 | * and hop count/pointer updating for IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE | ||
| 1303 | * MADs. | ||
| 1304 | * | ||
| 1305 | * This is called by the ib_mad module. | ||
| 1306 | */ | ||
| 1307 | int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | ||
| 1308 | struct ib_wc *in_wc, struct ib_grh *in_grh, | ||
| 1309 | struct ib_mad *in_mad, struct ib_mad *out_mad) | ||
| 1310 | { | ||
| 1311 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 1312 | int ret; | ||
| 1313 | |||
| 1314 | /* | ||
| 1315 | * Snapshot current HW counters to "clear" them. | ||
| 1316 | * This should be done when the driver is loaded except that for | ||
| 1317 | * some reason we get a zillion errors when brining up the link. | ||
| 1318 | */ | ||
| 1319 | if (dev->rcv_errors == 0) { | ||
| 1320 | struct ipath_layer_counters cntrs; | ||
| 1321 | |||
| 1322 | ipath_layer_get_counters(to_idev(ibdev)->dd, &cntrs); | ||
| 1323 | dev->rcv_errors++; | ||
| 1324 | dev->n_symbol_error_counter = cntrs.symbol_error_counter; | ||
| 1325 | dev->n_link_error_recovery_counter = | ||
| 1326 | cntrs.link_error_recovery_counter; | ||
| 1327 | dev->n_link_downed_counter = cntrs.link_downed_counter; | ||
| 1328 | dev->n_port_rcv_errors = cntrs.port_rcv_errors + 1; | ||
| 1329 | dev->n_port_rcv_remphys_errors = | ||
| 1330 | cntrs.port_rcv_remphys_errors; | ||
| 1331 | dev->n_port_xmit_discards = cntrs.port_xmit_discards; | ||
| 1332 | dev->n_port_xmit_data = cntrs.port_xmit_data; | ||
| 1333 | dev->n_port_rcv_data = cntrs.port_rcv_data; | ||
| 1334 | dev->n_port_xmit_packets = cntrs.port_xmit_packets; | ||
| 1335 | dev->n_port_rcv_packets = cntrs.port_rcv_packets; | ||
| 1336 | } | ||
| 1337 | switch (in_mad->mad_hdr.mgmt_class) { | ||
| 1338 | case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: | ||
| 1339 | case IB_MGMT_CLASS_SUBN_LID_ROUTED: | ||
| 1340 | ret = process_subn(ibdev, mad_flags, port_num, | ||
| 1341 | in_mad, out_mad); | ||
| 1342 | goto bail; | ||
| 1343 | case IB_MGMT_CLASS_PERF_MGMT: | ||
| 1344 | ret = process_perf(ibdev, port_num, in_mad, out_mad); | ||
| 1345 | goto bail; | ||
| 1346 | default: | ||
| 1347 | ret = IB_MAD_RESULT_SUCCESS; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | bail: | ||
| 1351 | return ret; | ||
| 1352 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c new file mode 100644 index 000000000000..69ffec66d45d --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_mr.c | |||
| @@ -0,0 +1,383 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <rdma/ib_pack.h> | ||
| 34 | #include <rdma/ib_smi.h> | ||
| 35 | |||
| 36 | #include "ipath_verbs.h" | ||
| 37 | |||
| 38 | /** | ||
| 39 | * ipath_get_dma_mr - get a DMA memory region | ||
| 40 | * @pd: protection domain for this memory region | ||
| 41 | * @acc: access flags | ||
| 42 | * | ||
| 43 | * Returns the memory region on success, otherwise returns an errno. | ||
| 44 | */ | ||
| 45 | struct ib_mr *ipath_get_dma_mr(struct ib_pd *pd, int acc) | ||
| 46 | { | ||
| 47 | struct ipath_mr *mr; | ||
| 48 | struct ib_mr *ret; | ||
| 49 | |||
| 50 | mr = kzalloc(sizeof *mr, GFP_KERNEL); | ||
| 51 | if (!mr) { | ||
| 52 | ret = ERR_PTR(-ENOMEM); | ||
| 53 | goto bail; | ||
| 54 | } | ||
| 55 | |||
| 56 | mr->mr.access_flags = acc; | ||
| 57 | ret = &mr->ibmr; | ||
| 58 | |||
| 59 | bail: | ||
| 60 | return ret; | ||
| 61 | } | ||
| 62 | |||
| 63 | static struct ipath_mr *alloc_mr(int count, | ||
| 64 | struct ipath_lkey_table *lk_table) | ||
| 65 | { | ||
| 66 | struct ipath_mr *mr; | ||
| 67 | int m, i = 0; | ||
| 68 | |||
| 69 | /* Allocate struct plus pointers to first level page tables. */ | ||
| 70 | m = (count + IPATH_SEGSZ - 1) / IPATH_SEGSZ; | ||
| 71 | mr = kmalloc(sizeof *mr + m * sizeof mr->mr.map[0], GFP_KERNEL); | ||
| 72 | if (!mr) | ||
| 73 | goto done; | ||
| 74 | |||
| 75 | /* Allocate first level page tables. */ | ||
| 76 | for (; i < m; i++) { | ||
| 77 | mr->mr.map[i] = kmalloc(sizeof *mr->mr.map[0], GFP_KERNEL); | ||
| 78 | if (!mr->mr.map[i]) | ||
| 79 | goto bail; | ||
| 80 | } | ||
| 81 | mr->mr.mapsz = m; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * ib_reg_phys_mr() will initialize mr->ibmr except for | ||
| 85 | * lkey and rkey. | ||
| 86 | */ | ||
| 87 | if (!ipath_alloc_lkey(lk_table, &mr->mr)) | ||
| 88 | goto bail; | ||
| 89 | mr->ibmr.rkey = mr->ibmr.lkey = mr->mr.lkey; | ||
| 90 | |||
| 91 | goto done; | ||
| 92 | |||
| 93 | bail: | ||
| 94 | while (i) { | ||
| 95 | i--; | ||
| 96 | kfree(mr->mr.map[i]); | ||
| 97 | } | ||
| 98 | kfree(mr); | ||
| 99 | mr = NULL; | ||
| 100 | |||
| 101 | done: | ||
| 102 | return mr; | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * ipath_reg_phys_mr - register a physical memory region | ||
| 107 | * @pd: protection domain for this memory region | ||
| 108 | * @buffer_list: pointer to the list of physical buffers to register | ||
| 109 | * @num_phys_buf: the number of physical buffers to register | ||
| 110 | * @iova_start: the starting address passed over IB which maps to this MR | ||
| 111 | * | ||
| 112 | * Returns the memory region on success, otherwise returns an errno. | ||
| 113 | */ | ||
| 114 | struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd, | ||
| 115 | struct ib_phys_buf *buffer_list, | ||
| 116 | int num_phys_buf, int acc, u64 *iova_start) | ||
| 117 | { | ||
| 118 | struct ipath_mr *mr; | ||
| 119 | int n, m, i; | ||
| 120 | struct ib_mr *ret; | ||
| 121 | |||
| 122 | mr = alloc_mr(num_phys_buf, &to_idev(pd->device)->lk_table); | ||
| 123 | if (mr == NULL) { | ||
| 124 | ret = ERR_PTR(-ENOMEM); | ||
| 125 | goto bail; | ||
| 126 | } | ||
| 127 | |||
| 128 | mr->mr.user_base = *iova_start; | ||
| 129 | mr->mr.iova = *iova_start; | ||
| 130 | mr->mr.length = 0; | ||
| 131 | mr->mr.offset = 0; | ||
| 132 | mr->mr.access_flags = acc; | ||
| 133 | mr->mr.max_segs = num_phys_buf; | ||
| 134 | |||
| 135 | m = 0; | ||
| 136 | n = 0; | ||
| 137 | for (i = 0; i < num_phys_buf; i++) { | ||
| 138 | mr->mr.map[m]->segs[n].vaddr = | ||
| 139 | phys_to_virt(buffer_list[i].addr); | ||
| 140 | mr->mr.map[m]->segs[n].length = buffer_list[i].size; | ||
| 141 | mr->mr.length += buffer_list[i].size; | ||
| 142 | n++; | ||
| 143 | if (n == IPATH_SEGSZ) { | ||
| 144 | m++; | ||
| 145 | n = 0; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | ret = &mr->ibmr; | ||
| 150 | |||
| 151 | bail: | ||
| 152 | return ret; | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * ipath_reg_user_mr - register a userspace memory region | ||
| 157 | * @pd: protection domain for this memory region | ||
| 158 | * @region: the user memory region | ||
| 159 | * @mr_access_flags: access flags for this memory region | ||
| 160 | * @udata: unused by the InfiniPath driver | ||
| 161 | * | ||
| 162 | * Returns the memory region on success, otherwise returns an errno. | ||
| 163 | */ | ||
| 164 | struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region, | ||
| 165 | int mr_access_flags, struct ib_udata *udata) | ||
| 166 | { | ||
| 167 | struct ipath_mr *mr; | ||
| 168 | struct ib_umem_chunk *chunk; | ||
| 169 | int n, m, i; | ||
| 170 | struct ib_mr *ret; | ||
| 171 | |||
| 172 | n = 0; | ||
| 173 | list_for_each_entry(chunk, ®ion->chunk_list, list) | ||
| 174 | n += chunk->nents; | ||
| 175 | |||
| 176 | mr = alloc_mr(n, &to_idev(pd->device)->lk_table); | ||
| 177 | if (!mr) { | ||
| 178 | ret = ERR_PTR(-ENOMEM); | ||
| 179 | goto bail; | ||
| 180 | } | ||
| 181 | |||
| 182 | mr->mr.user_base = region->user_base; | ||
| 183 | mr->mr.iova = region->virt_base; | ||
| 184 | mr->mr.length = region->length; | ||
| 185 | mr->mr.offset = region->offset; | ||
| 186 | mr->mr.access_flags = mr_access_flags; | ||
| 187 | mr->mr.max_segs = n; | ||
| 188 | |||
| 189 | m = 0; | ||
| 190 | n = 0; | ||
| 191 | list_for_each_entry(chunk, ®ion->chunk_list, list) { | ||
| 192 | for (i = 0; i < chunk->nmap; i++) { | ||
| 193 | mr->mr.map[m]->segs[n].vaddr = | ||
| 194 | page_address(chunk->page_list[i].page); | ||
| 195 | mr->mr.map[m]->segs[n].length = region->page_size; | ||
| 196 | n++; | ||
| 197 | if (n == IPATH_SEGSZ) { | ||
| 198 | m++; | ||
| 199 | n = 0; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | ret = &mr->ibmr; | ||
| 204 | |||
| 205 | bail: | ||
| 206 | return ret; | ||
| 207 | } | ||
| 208 | |||
| 209 | /** | ||
| 210 | * ipath_dereg_mr - unregister and free a memory region | ||
| 211 | * @ibmr: the memory region to free | ||
| 212 | * | ||
| 213 | * Returns 0 on success. | ||
| 214 | * | ||
| 215 | * Note that this is called to free MRs created by ipath_get_dma_mr() | ||
| 216 | * or ipath_reg_user_mr(). | ||
| 217 | */ | ||
| 218 | int ipath_dereg_mr(struct ib_mr *ibmr) | ||
| 219 | { | ||
| 220 | struct ipath_mr *mr = to_imr(ibmr); | ||
| 221 | int i; | ||
| 222 | |||
| 223 | ipath_free_lkey(&to_idev(ibmr->device)->lk_table, ibmr->lkey); | ||
| 224 | i = mr->mr.mapsz; | ||
| 225 | while (i) { | ||
| 226 | i--; | ||
| 227 | kfree(mr->mr.map[i]); | ||
| 228 | } | ||
| 229 | kfree(mr); | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | /** | ||
| 234 | * ipath_alloc_fmr - allocate a fast memory region | ||
| 235 | * @pd: the protection domain for this memory region | ||
| 236 | * @mr_access_flags: access flags for this memory region | ||
| 237 | * @fmr_attr: fast memory region attributes | ||
| 238 | * | ||
| 239 | * Returns the memory region on success, otherwise returns an errno. | ||
| 240 | */ | ||
| 241 | struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags, | ||
| 242 | struct ib_fmr_attr *fmr_attr) | ||
| 243 | { | ||
| 244 | struct ipath_fmr *fmr; | ||
| 245 | int m, i = 0; | ||
| 246 | struct ib_fmr *ret; | ||
| 247 | |||
| 248 | /* Allocate struct plus pointers to first level page tables. */ | ||
| 249 | m = (fmr_attr->max_pages + IPATH_SEGSZ - 1) / IPATH_SEGSZ; | ||
| 250 | fmr = kmalloc(sizeof *fmr + m * sizeof fmr->mr.map[0], GFP_KERNEL); | ||
| 251 | if (!fmr) | ||
| 252 | goto bail; | ||
| 253 | |||
| 254 | /* Allocate first level page tables. */ | ||
| 255 | for (; i < m; i++) { | ||
| 256 | fmr->mr.map[i] = kmalloc(sizeof *fmr->mr.map[0], | ||
| 257 | GFP_KERNEL); | ||
| 258 | if (!fmr->mr.map[i]) | ||
| 259 | goto bail; | ||
| 260 | } | ||
| 261 | fmr->mr.mapsz = m; | ||
| 262 | |||
| 263 | /* | ||
| 264 | * ib_alloc_fmr() will initialize fmr->ibfmr except for lkey & | ||
| 265 | * rkey. | ||
| 266 | */ | ||
| 267 | if (!ipath_alloc_lkey(&to_idev(pd->device)->lk_table, &fmr->mr)) | ||
| 268 | goto bail; | ||
| 269 | fmr->ibfmr.rkey = fmr->ibfmr.lkey = fmr->mr.lkey; | ||
| 270 | /* | ||
| 271 | * Resources are allocated but no valid mapping (RKEY can't be | ||
| 272 | * used). | ||
| 273 | */ | ||
| 274 | fmr->mr.user_base = 0; | ||
| 275 | fmr->mr.iova = 0; | ||
| 276 | fmr->mr.length = 0; | ||
| 277 | fmr->mr.offset = 0; | ||
| 278 | fmr->mr.access_flags = mr_access_flags; | ||
| 279 | fmr->mr.max_segs = fmr_attr->max_pages; | ||
| 280 | fmr->page_shift = fmr_attr->page_shift; | ||
| 281 | |||
| 282 | ret = &fmr->ibfmr; | ||
| 283 | goto done; | ||
| 284 | |||
| 285 | bail: | ||
| 286 | while (i) | ||
| 287 | kfree(fmr->mr.map[--i]); | ||
| 288 | kfree(fmr); | ||
| 289 | ret = ERR_PTR(-ENOMEM); | ||
| 290 | |||
| 291 | done: | ||
| 292 | return ret; | ||
| 293 | } | ||
| 294 | |||
| 295 | /** | ||
| 296 | * ipath_map_phys_fmr - set up a fast memory region | ||
| 297 | * @ibmfr: the fast memory region to set up | ||
| 298 | * @page_list: the list of pages to associate with the fast memory region | ||
| 299 | * @list_len: the number of pages to associate with the fast memory region | ||
| 300 | * @iova: the virtual address of the start of the fast memory region | ||
| 301 | * | ||
| 302 | * This may be called from interrupt context. | ||
| 303 | */ | ||
| 304 | |||
| 305 | int ipath_map_phys_fmr(struct ib_fmr *ibfmr, u64 * page_list, | ||
| 306 | int list_len, u64 iova) | ||
| 307 | { | ||
| 308 | struct ipath_fmr *fmr = to_ifmr(ibfmr); | ||
| 309 | struct ipath_lkey_table *rkt; | ||
| 310 | unsigned long flags; | ||
| 311 | int m, n, i; | ||
| 312 | u32 ps; | ||
| 313 | int ret; | ||
| 314 | |||
| 315 | if (list_len > fmr->mr.max_segs) { | ||
| 316 | ret = -EINVAL; | ||
| 317 | goto bail; | ||
| 318 | } | ||
| 319 | rkt = &to_idev(ibfmr->device)->lk_table; | ||
| 320 | spin_lock_irqsave(&rkt->lock, flags); | ||
| 321 | fmr->mr.user_base = iova; | ||
| 322 | fmr->mr.iova = iova; | ||
| 323 | ps = 1 << fmr->page_shift; | ||
| 324 | fmr->mr.length = list_len * ps; | ||
| 325 | m = 0; | ||
| 326 | n = 0; | ||
| 327 | ps = 1 << fmr->page_shift; | ||
| 328 | for (i = 0; i < list_len; i++) { | ||
| 329 | fmr->mr.map[m]->segs[n].vaddr = phys_to_virt(page_list[i]); | ||
| 330 | fmr->mr.map[m]->segs[n].length = ps; | ||
| 331 | if (++n == IPATH_SEGSZ) { | ||
| 332 | m++; | ||
| 333 | n = 0; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | spin_unlock_irqrestore(&rkt->lock, flags); | ||
| 337 | ret = 0; | ||
| 338 | |||
| 339 | bail: | ||
| 340 | return ret; | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * ipath_unmap_fmr - unmap fast memory regions | ||
| 345 | * @fmr_list: the list of fast memory regions to unmap | ||
| 346 | * | ||
| 347 | * Returns 0 on success. | ||
| 348 | */ | ||
| 349 | int ipath_unmap_fmr(struct list_head *fmr_list) | ||
| 350 | { | ||
| 351 | struct ipath_fmr *fmr; | ||
| 352 | struct ipath_lkey_table *rkt; | ||
| 353 | unsigned long flags; | ||
| 354 | |||
| 355 | list_for_each_entry(fmr, fmr_list, ibfmr.list) { | ||
| 356 | rkt = &to_idev(fmr->ibfmr.device)->lk_table; | ||
| 357 | spin_lock_irqsave(&rkt->lock, flags); | ||
| 358 | fmr->mr.user_base = 0; | ||
| 359 | fmr->mr.iova = 0; | ||
| 360 | fmr->mr.length = 0; | ||
| 361 | spin_unlock_irqrestore(&rkt->lock, flags); | ||
| 362 | } | ||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | /** | ||
| 367 | * ipath_dealloc_fmr - deallocate a fast memory region | ||
| 368 | * @ibfmr: the fast memory region to deallocate | ||
| 369 | * | ||
| 370 | * Returns 0 on success. | ||
| 371 | */ | ||
| 372 | int ipath_dealloc_fmr(struct ib_fmr *ibfmr) | ||
| 373 | { | ||
| 374 | struct ipath_fmr *fmr = to_ifmr(ibfmr); | ||
| 375 | int i; | ||
| 376 | |||
| 377 | ipath_free_lkey(&to_idev(ibfmr->device)->lk_table, ibfmr->lkey); | ||
| 378 | i = fmr->mr.mapsz; | ||
| 379 | while (i) | ||
| 380 | kfree(fmr->mr.map[--i]); | ||
| 381 | kfree(fmr); | ||
| 382 | return 0; | ||
| 383 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_pe800.c new file mode 100644 index 000000000000..e693a7a82667 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_pe800.c | |||
| @@ -0,0 +1,1247 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | /* | ||
| 33 | * This file contains all of the code that is specific to the | ||
| 34 | * InfiniPath PE-800 chip. | ||
| 35 | */ | ||
| 36 | |||
| 37 | #include <linux/interrupt.h> | ||
| 38 | #include <linux/pci.h> | ||
| 39 | #include <linux/delay.h> | ||
| 40 | |||
| 41 | |||
| 42 | #include "ipath_kernel.h" | ||
| 43 | #include "ipath_registers.h" | ||
| 44 | |||
| 45 | /* | ||
| 46 | * This file contains all the chip-specific register information and | ||
| 47 | * access functions for the PathScale PE800, the PCI-Express chip. | ||
| 48 | * | ||
| 49 | * This lists the InfiniPath PE800 registers, in the actual chip layout. | ||
| 50 | * This structure should never be directly accessed. | ||
| 51 | */ | ||
| 52 | struct _infinipath_do_not_use_kernel_regs { | ||
| 53 | unsigned long long Revision; | ||
| 54 | unsigned long long Control; | ||
| 55 | unsigned long long PageAlign; | ||
| 56 | unsigned long long PortCnt; | ||
| 57 | unsigned long long DebugPortSelect; | ||
| 58 | unsigned long long Reserved0; | ||
| 59 | unsigned long long SendRegBase; | ||
| 60 | unsigned long long UserRegBase; | ||
| 61 | unsigned long long CounterRegBase; | ||
| 62 | unsigned long long Scratch; | ||
| 63 | unsigned long long Reserved1; | ||
| 64 | unsigned long long Reserved2; | ||
| 65 | unsigned long long IntBlocked; | ||
| 66 | unsigned long long IntMask; | ||
| 67 | unsigned long long IntStatus; | ||
| 68 | unsigned long long IntClear; | ||
| 69 | unsigned long long ErrorMask; | ||
| 70 | unsigned long long ErrorStatus; | ||
| 71 | unsigned long long ErrorClear; | ||
| 72 | unsigned long long HwErrMask; | ||
| 73 | unsigned long long HwErrStatus; | ||
| 74 | unsigned long long HwErrClear; | ||
| 75 | unsigned long long HwDiagCtrl; | ||
| 76 | unsigned long long MDIO; | ||
| 77 | unsigned long long IBCStatus; | ||
| 78 | unsigned long long IBCCtrl; | ||
| 79 | unsigned long long ExtStatus; | ||
| 80 | unsigned long long ExtCtrl; | ||
| 81 | unsigned long long GPIOOut; | ||
| 82 | unsigned long long GPIOMask; | ||
| 83 | unsigned long long GPIOStatus; | ||
| 84 | unsigned long long GPIOClear; | ||
| 85 | unsigned long long RcvCtrl; | ||
| 86 | unsigned long long RcvBTHQP; | ||
| 87 | unsigned long long RcvHdrSize; | ||
| 88 | unsigned long long RcvHdrCnt; | ||
| 89 | unsigned long long RcvHdrEntSize; | ||
| 90 | unsigned long long RcvTIDBase; | ||
| 91 | unsigned long long RcvTIDCnt; | ||
| 92 | unsigned long long RcvEgrBase; | ||
| 93 | unsigned long long RcvEgrCnt; | ||
| 94 | unsigned long long RcvBufBase; | ||
| 95 | unsigned long long RcvBufSize; | ||
| 96 | unsigned long long RxIntMemBase; | ||
| 97 | unsigned long long RxIntMemSize; | ||
| 98 | unsigned long long RcvPartitionKey; | ||
| 99 | unsigned long long Reserved3; | ||
| 100 | unsigned long long RcvPktLEDCnt; | ||
| 101 | unsigned long long Reserved4[8]; | ||
| 102 | unsigned long long SendCtrl; | ||
| 103 | unsigned long long SendPIOBufBase; | ||
| 104 | unsigned long long SendPIOSize; | ||
| 105 | unsigned long long SendPIOBufCnt; | ||
| 106 | unsigned long long SendPIOAvailAddr; | ||
| 107 | unsigned long long TxIntMemBase; | ||
| 108 | unsigned long long TxIntMemSize; | ||
| 109 | unsigned long long Reserved5; | ||
| 110 | unsigned long long PCIeRBufTestReg0; | ||
| 111 | unsigned long long PCIeRBufTestReg1; | ||
| 112 | unsigned long long Reserved51[6]; | ||
| 113 | unsigned long long SendBufferError; | ||
| 114 | unsigned long long SendBufferErrorCONT1; | ||
| 115 | unsigned long long Reserved6SBE[6]; | ||
| 116 | unsigned long long RcvHdrAddr0; | ||
| 117 | unsigned long long RcvHdrAddr1; | ||
| 118 | unsigned long long RcvHdrAddr2; | ||
| 119 | unsigned long long RcvHdrAddr3; | ||
| 120 | unsigned long long RcvHdrAddr4; | ||
| 121 | unsigned long long Reserved7RHA[11]; | ||
| 122 | unsigned long long RcvHdrTailAddr0; | ||
| 123 | unsigned long long RcvHdrTailAddr1; | ||
| 124 | unsigned long long RcvHdrTailAddr2; | ||
| 125 | unsigned long long RcvHdrTailAddr3; | ||
| 126 | unsigned long long RcvHdrTailAddr4; | ||
| 127 | unsigned long long Reserved8RHTA[11]; | ||
| 128 | unsigned long long Reserved9SW[8]; | ||
| 129 | unsigned long long SerdesConfig0; | ||
| 130 | unsigned long long SerdesConfig1; | ||
| 131 | unsigned long long SerdesStatus; | ||
| 132 | unsigned long long XGXSConfig; | ||
| 133 | unsigned long long IBPLLCfg; | ||
| 134 | unsigned long long Reserved10SW2[3]; | ||
| 135 | unsigned long long PCIEQ0SerdesConfig0; | ||
| 136 | unsigned long long PCIEQ0SerdesConfig1; | ||
| 137 | unsigned long long PCIEQ0SerdesStatus; | ||
| 138 | unsigned long long Reserved11; | ||
| 139 | unsigned long long PCIEQ1SerdesConfig0; | ||
| 140 | unsigned long long PCIEQ1SerdesConfig1; | ||
| 141 | unsigned long long PCIEQ1SerdesStatus; | ||
| 142 | unsigned long long Reserved12; | ||
| 143 | }; | ||
| 144 | |||
| 145 | #define IPATH_KREG_OFFSET(field) (offsetof(struct \ | ||
| 146 | _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | ||
| 147 | #define IPATH_CREG_OFFSET(field) (offsetof( \ | ||
| 148 | struct infinipath_counters, field) / sizeof(u64)) | ||
| 149 | |||
| 150 | static const struct ipath_kregs ipath_pe_kregs = { | ||
| 151 | .kr_control = IPATH_KREG_OFFSET(Control), | ||
| 152 | .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), | ||
| 153 | .kr_debugportselect = IPATH_KREG_OFFSET(DebugPortSelect), | ||
| 154 | .kr_errorclear = IPATH_KREG_OFFSET(ErrorClear), | ||
| 155 | .kr_errormask = IPATH_KREG_OFFSET(ErrorMask), | ||
| 156 | .kr_errorstatus = IPATH_KREG_OFFSET(ErrorStatus), | ||
| 157 | .kr_extctrl = IPATH_KREG_OFFSET(ExtCtrl), | ||
| 158 | .kr_extstatus = IPATH_KREG_OFFSET(ExtStatus), | ||
| 159 | .kr_gpio_clear = IPATH_KREG_OFFSET(GPIOClear), | ||
| 160 | .kr_gpio_mask = IPATH_KREG_OFFSET(GPIOMask), | ||
| 161 | .kr_gpio_out = IPATH_KREG_OFFSET(GPIOOut), | ||
| 162 | .kr_gpio_status = IPATH_KREG_OFFSET(GPIOStatus), | ||
| 163 | .kr_hwdiagctrl = IPATH_KREG_OFFSET(HwDiagCtrl), | ||
| 164 | .kr_hwerrclear = IPATH_KREG_OFFSET(HwErrClear), | ||
| 165 | .kr_hwerrmask = IPATH_KREG_OFFSET(HwErrMask), | ||
| 166 | .kr_hwerrstatus = IPATH_KREG_OFFSET(HwErrStatus), | ||
| 167 | .kr_ibcctrl = IPATH_KREG_OFFSET(IBCCtrl), | ||
| 168 | .kr_ibcstatus = IPATH_KREG_OFFSET(IBCStatus), | ||
| 169 | .kr_intblocked = IPATH_KREG_OFFSET(IntBlocked), | ||
| 170 | .kr_intclear = IPATH_KREG_OFFSET(IntClear), | ||
| 171 | .kr_intmask = IPATH_KREG_OFFSET(IntMask), | ||
| 172 | .kr_intstatus = IPATH_KREG_OFFSET(IntStatus), | ||
| 173 | .kr_mdio = IPATH_KREG_OFFSET(MDIO), | ||
| 174 | .kr_pagealign = IPATH_KREG_OFFSET(PageAlign), | ||
| 175 | .kr_partitionkey = IPATH_KREG_OFFSET(RcvPartitionKey), | ||
| 176 | .kr_portcnt = IPATH_KREG_OFFSET(PortCnt), | ||
| 177 | .kr_rcvbthqp = IPATH_KREG_OFFSET(RcvBTHQP), | ||
| 178 | .kr_rcvbufbase = IPATH_KREG_OFFSET(RcvBufBase), | ||
| 179 | .kr_rcvbufsize = IPATH_KREG_OFFSET(RcvBufSize), | ||
| 180 | .kr_rcvctrl = IPATH_KREG_OFFSET(RcvCtrl), | ||
| 181 | .kr_rcvegrbase = IPATH_KREG_OFFSET(RcvEgrBase), | ||
| 182 | .kr_rcvegrcnt = IPATH_KREG_OFFSET(RcvEgrCnt), | ||
| 183 | .kr_rcvhdrcnt = IPATH_KREG_OFFSET(RcvHdrCnt), | ||
| 184 | .kr_rcvhdrentsize = IPATH_KREG_OFFSET(RcvHdrEntSize), | ||
| 185 | .kr_rcvhdrsize = IPATH_KREG_OFFSET(RcvHdrSize), | ||
| 186 | .kr_rcvintmembase = IPATH_KREG_OFFSET(RxIntMemBase), | ||
| 187 | .kr_rcvintmemsize = IPATH_KREG_OFFSET(RxIntMemSize), | ||
| 188 | .kr_rcvtidbase = IPATH_KREG_OFFSET(RcvTIDBase), | ||
| 189 | .kr_rcvtidcnt = IPATH_KREG_OFFSET(RcvTIDCnt), | ||
| 190 | .kr_revision = IPATH_KREG_OFFSET(Revision), | ||
| 191 | .kr_scratch = IPATH_KREG_OFFSET(Scratch), | ||
| 192 | .kr_sendbuffererror = IPATH_KREG_OFFSET(SendBufferError), | ||
| 193 | .kr_sendctrl = IPATH_KREG_OFFSET(SendCtrl), | ||
| 194 | .kr_sendpioavailaddr = IPATH_KREG_OFFSET(SendPIOAvailAddr), | ||
| 195 | .kr_sendpiobufbase = IPATH_KREG_OFFSET(SendPIOBufBase), | ||
| 196 | .kr_sendpiobufcnt = IPATH_KREG_OFFSET(SendPIOBufCnt), | ||
| 197 | .kr_sendpiosize = IPATH_KREG_OFFSET(SendPIOSize), | ||
| 198 | .kr_sendregbase = IPATH_KREG_OFFSET(SendRegBase), | ||
| 199 | .kr_txintmembase = IPATH_KREG_OFFSET(TxIntMemBase), | ||
| 200 | .kr_txintmemsize = IPATH_KREG_OFFSET(TxIntMemSize), | ||
| 201 | .kr_userregbase = IPATH_KREG_OFFSET(UserRegBase), | ||
| 202 | .kr_serdesconfig0 = IPATH_KREG_OFFSET(SerdesConfig0), | ||
| 203 | .kr_serdesconfig1 = IPATH_KREG_OFFSET(SerdesConfig1), | ||
| 204 | .kr_serdesstatus = IPATH_KREG_OFFSET(SerdesStatus), | ||
| 205 | .kr_xgxsconfig = IPATH_KREG_OFFSET(XGXSConfig), | ||
| 206 | .kr_ibpllcfg = IPATH_KREG_OFFSET(IBPLLCfg), | ||
| 207 | |||
| 208 | /* | ||
| 209 | * These should not be used directly via ipath_read_kreg64(), | ||
| 210 | * use them with ipath_read_kreg64_port() | ||
| 211 | */ | ||
| 212 | .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), | ||
| 213 | .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0), | ||
| 214 | |||
| 215 | /* This group is pe-800-specific; and used only in this file */ | ||
| 216 | /* The rcvpktled register controls one of the debug port signals, so | ||
| 217 | * a packet activity LED can be connected to it. */ | ||
| 218 | .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt), | ||
| 219 | .kr_pcierbuftestreg0 = IPATH_KREG_OFFSET(PCIeRBufTestReg0), | ||
| 220 | .kr_pcierbuftestreg1 = IPATH_KREG_OFFSET(PCIeRBufTestReg1), | ||
| 221 | .kr_pcieq0serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig0), | ||
| 222 | .kr_pcieq0serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig1), | ||
| 223 | .kr_pcieq0serdesstatus = IPATH_KREG_OFFSET(PCIEQ0SerdesStatus), | ||
| 224 | .kr_pcieq1serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig0), | ||
| 225 | .kr_pcieq1serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig1), | ||
| 226 | .kr_pcieq1serdesstatus = IPATH_KREG_OFFSET(PCIEQ1SerdesStatus) | ||
| 227 | }; | ||
| 228 | |||
| 229 | static const struct ipath_cregs ipath_pe_cregs = { | ||
| 230 | .cr_badformatcnt = IPATH_CREG_OFFSET(RxBadFormatCnt), | ||
| 231 | .cr_erricrccnt = IPATH_CREG_OFFSET(RxICRCErrCnt), | ||
| 232 | .cr_errlinkcnt = IPATH_CREG_OFFSET(RxLinkProblemCnt), | ||
| 233 | .cr_errlpcrccnt = IPATH_CREG_OFFSET(RxLPCRCErrCnt), | ||
| 234 | .cr_errpkey = IPATH_CREG_OFFSET(RxPKeyMismatchCnt), | ||
| 235 | .cr_errrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowCtrlErrCnt), | ||
| 236 | .cr_err_rlencnt = IPATH_CREG_OFFSET(RxLenErrCnt), | ||
| 237 | .cr_errslencnt = IPATH_CREG_OFFSET(TxLenErrCnt), | ||
| 238 | .cr_errtidfull = IPATH_CREG_OFFSET(RxTIDFullErrCnt), | ||
| 239 | .cr_errtidvalid = IPATH_CREG_OFFSET(RxTIDValidErrCnt), | ||
| 240 | .cr_errvcrccnt = IPATH_CREG_OFFSET(RxVCRCErrCnt), | ||
| 241 | .cr_ibstatuschange = IPATH_CREG_OFFSET(IBStatusChangeCnt), | ||
| 242 | .cr_intcnt = IPATH_CREG_OFFSET(LBIntCnt), | ||
| 243 | .cr_invalidrlencnt = IPATH_CREG_OFFSET(RxMaxMinLenErrCnt), | ||
| 244 | .cr_invalidslencnt = IPATH_CREG_OFFSET(TxMaxMinLenErrCnt), | ||
| 245 | .cr_lbflowstallcnt = IPATH_CREG_OFFSET(LBFlowStallCnt), | ||
| 246 | .cr_pktrcvcnt = IPATH_CREG_OFFSET(RxDataPktCnt), | ||
| 247 | .cr_pktrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowPktCnt), | ||
| 248 | .cr_pktsendcnt = IPATH_CREG_OFFSET(TxDataPktCnt), | ||
| 249 | .cr_pktsendflowcnt = IPATH_CREG_OFFSET(TxFlowPktCnt), | ||
| 250 | .cr_portovflcnt = IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt), | ||
| 251 | .cr_rcvebpcnt = IPATH_CREG_OFFSET(RxEBPCnt), | ||
| 252 | .cr_rcvovflcnt = IPATH_CREG_OFFSET(RxBufOvflCnt), | ||
| 253 | .cr_senddropped = IPATH_CREG_OFFSET(TxDroppedPktCnt), | ||
| 254 | .cr_sendstallcnt = IPATH_CREG_OFFSET(TxFlowStallCnt), | ||
| 255 | .cr_sendunderruncnt = IPATH_CREG_OFFSET(TxUnderrunCnt), | ||
| 256 | .cr_wordrcvcnt = IPATH_CREG_OFFSET(RxDwordCnt), | ||
| 257 | .cr_wordsendcnt = IPATH_CREG_OFFSET(TxDwordCnt), | ||
| 258 | .cr_unsupvlcnt = IPATH_CREG_OFFSET(TxUnsupVLErrCnt), | ||
| 259 | .cr_rxdroppktcnt = IPATH_CREG_OFFSET(RxDroppedPktCnt), | ||
| 260 | .cr_iblinkerrrecovcnt = IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt), | ||
| 261 | .cr_iblinkdowncnt = IPATH_CREG_OFFSET(IBLinkDownedCnt), | ||
| 262 | .cr_ibsymbolerrcnt = IPATH_CREG_OFFSET(IBSymbolErrCnt) | ||
| 263 | }; | ||
| 264 | |||
| 265 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | ||
| 266 | #define INFINIPATH_I_RCVURG_MASK 0x1F | ||
| 267 | #define INFINIPATH_I_RCVAVAIL_MASK 0x1F | ||
| 268 | |||
| 269 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ | ||
| 270 | #define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL | ||
| 271 | #define INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT 0 | ||
| 272 | #define INFINIPATH_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL | ||
| 273 | #define INFINIPATH_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL | ||
| 274 | #define INFINIPATH_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL | ||
| 275 | #define INFINIPATH_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL | ||
| 276 | #define INFINIPATH_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL | ||
| 277 | #define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL | ||
| 278 | #define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL | ||
| 279 | #define INFINIPATH_HWE_PCIE1PLLFAILED 0x0400000000000000ULL | ||
| 280 | #define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL | ||
| 281 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL | ||
| 282 | |||
| 283 | /* kr_extstatus bits */ | ||
| 284 | #define INFINIPATH_EXTS_FREQSEL 0x2 | ||
| 285 | #define INFINIPATH_EXTS_SERDESSEL 0x4 | ||
| 286 | #define INFINIPATH_EXTS_MEMBIST_ENDTEST 0x0000000000004000 | ||
| 287 | #define INFINIPATH_EXTS_MEMBIST_FOUND 0x0000000000008000 | ||
| 288 | |||
| 289 | #define _IPATH_GPIO_SDA_NUM 1 | ||
| 290 | #define _IPATH_GPIO_SCL_NUM 0 | ||
| 291 | |||
| 292 | #define IPATH_GPIO_SDA (1ULL << \ | ||
| 293 | (_IPATH_GPIO_SDA_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) | ||
| 294 | #define IPATH_GPIO_SCL (1ULL << \ | ||
| 295 | (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) | ||
| 296 | |||
| 297 | /** | ||
| 298 | * ipath_pe_handle_hwerrors - display hardware errors. | ||
| 299 | * @dd: the infinipath device | ||
| 300 | * @msg: the output buffer | ||
| 301 | * @msgl: the size of the output buffer | ||
| 302 | * | ||
| 303 | * Use same msg buffer as regular errors to avoid excessive stack | ||
| 304 | * use. Most hardware errors are catastrophic, but for right now, | ||
| 305 | * we'll print them and continue. We reuse the same message buffer as | ||
| 306 | * ipath_handle_errors() to avoid excessive stack usage. | ||
| 307 | */ | ||
| 308 | void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | ||
| 309 | size_t msgl) | ||
| 310 | { | ||
| 311 | ipath_err_t hwerrs; | ||
| 312 | u32 bits, ctrl; | ||
| 313 | int isfatal = 0; | ||
| 314 | char bitsmsg[64]; | ||
| 315 | |||
| 316 | hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); | ||
| 317 | if (!hwerrs) { | ||
| 318 | /* | ||
| 319 | * better than printing cofusing messages | ||
| 320 | * This seems to be related to clearing the crc error, or | ||
| 321 | * the pll error during init. | ||
| 322 | */ | ||
| 323 | ipath_cdbg(VERBOSE, "Called but no hardware errors set\n"); | ||
| 324 | return; | ||
| 325 | } else if (hwerrs == ~0ULL) { | ||
| 326 | ipath_dev_err(dd, "Read of hardware error status failed " | ||
| 327 | "(all bits set); ignoring\n"); | ||
| 328 | return; | ||
| 329 | } | ||
| 330 | ipath_stats.sps_hwerrs++; | ||
| 331 | |||
| 332 | /* Always clear the error status register, except MEMBISTFAIL, | ||
| 333 | * regardless of whether we continue or stop using the chip. | ||
| 334 | * We want that set so we know it failed, even across driver reload. | ||
| 335 | * We'll still ignore it in the hwerrmask. We do this partly for | ||
| 336 | * diagnostics, but also for support */ | ||
| 337 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 338 | hwerrs&~INFINIPATH_HWE_MEMBISTFAILED); | ||
| 339 | |||
| 340 | hwerrs &= dd->ipath_hwerrmask; | ||
| 341 | |||
| 342 | /* | ||
| 343 | * make sure we get this much out, unless told to be quiet, | ||
| 344 | * or it's occurred within the last 5 seconds | ||
| 345 | */ | ||
| 346 | if ((hwerrs & ~dd->ipath_lasthwerror) || | ||
| 347 | (ipath_debug & __IPATH_VERBDBG)) | ||
| 348 | dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " | ||
| 349 | "(cleared)\n", (unsigned long long) hwerrs); | ||
| 350 | dd->ipath_lasthwerror |= hwerrs; | ||
| 351 | |||
| 352 | if (hwerrs & ~infinipath_hwe_bitsextant) | ||
| 353 | ipath_dev_err(dd, "hwerror interrupt with unknown errors " | ||
| 354 | "%llx set\n", (unsigned long long) | ||
| 355 | (hwerrs & ~infinipath_hwe_bitsextant)); | ||
| 356 | |||
| 357 | ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); | ||
| 358 | if (ctrl & INFINIPATH_C_FREEZEMODE) { | ||
| 359 | if (hwerrs) { | ||
| 360 | /* | ||
| 361 | * if any set that we aren't ignoring only make the | ||
| 362 | * complaint once, in case it's stuck or recurring, | ||
| 363 | * and we get here multiple times | ||
| 364 | */ | ||
| 365 | if (dd->ipath_flags & IPATH_INITTED) { | ||
| 366 | ipath_dev_err(dd, "Fatal Error (freeze " | ||
| 367 | "mode), no longer usable\n"); | ||
| 368 | isfatal = 1; | ||
| 369 | } | ||
| 370 | /* | ||
| 371 | * Mark as having had an error for driver, and also | ||
| 372 | * for /sys and status word mapped to user programs. | ||
| 373 | * This marks unit as not usable, until reset | ||
| 374 | */ | ||
| 375 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; | ||
| 376 | *dd->ipath_statusp |= IPATH_STATUS_HWERROR; | ||
| 377 | dd->ipath_flags &= ~IPATH_INITTED; | ||
| 378 | } else { | ||
| 379 | ipath_dbg("Clearing freezemode on ignored hardware " | ||
| 380 | "error\n"); | ||
| 381 | ctrl &= ~INFINIPATH_C_FREEZEMODE; | ||
| 382 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 383 | ctrl); | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | *msg = '\0'; | ||
| 388 | |||
| 389 | if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { | ||
| 390 | strlcat(msg, "[Memory BIST test failed, PE-800 unusable]", | ||
| 391 | msgl); | ||
| 392 | /* ignore from now on, so disable until driver reloaded */ | ||
| 393 | *dd->ipath_statusp |= IPATH_STATUS_HWERROR; | ||
| 394 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED; | ||
| 395 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 396 | dd->ipath_hwerrmask); | ||
| 397 | } | ||
| 398 | if (hwerrs & (INFINIPATH_HWE_RXEMEMPARITYERR_MASK | ||
| 399 | << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT)) { | ||
| 400 | bits = (u32) ((hwerrs >> | ||
| 401 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) & | ||
| 402 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK); | ||
| 403 | snprintf(bitsmsg, sizeof bitsmsg, "[RXE Parity Errs %x] ", | ||
| 404 | bits); | ||
| 405 | strlcat(msg, bitsmsg, msgl); | ||
| 406 | } | ||
| 407 | if (hwerrs & (INFINIPATH_HWE_TXEMEMPARITYERR_MASK | ||
| 408 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) { | ||
| 409 | bits = (u32) ((hwerrs >> | ||
| 410 | INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) & | ||
| 411 | INFINIPATH_HWE_TXEMEMPARITYERR_MASK); | ||
| 412 | snprintf(bitsmsg, sizeof bitsmsg, "[TXE Parity Errs %x] ", | ||
| 413 | bits); | ||
| 414 | strlcat(msg, bitsmsg, msgl); | ||
| 415 | } | ||
| 416 | if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK | ||
| 417 | << INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) { | ||
| 418 | bits = (u32) ((hwerrs >> | ||
| 419 | INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) & | ||
| 420 | INFINIPATH_HWE_PCIEMEMPARITYERR_MASK); | ||
| 421 | snprintf(bitsmsg, sizeof bitsmsg, | ||
| 422 | "[PCIe Mem Parity Errs %x] ", bits); | ||
| 423 | strlcat(msg, bitsmsg, msgl); | ||
| 424 | } | ||
| 425 | if (hwerrs & INFINIPATH_HWE_IBCBUSTOSPCPARITYERR) | ||
| 426 | strlcat(msg, "[IB2IPATH Parity]", msgl); | ||
| 427 | if (hwerrs & INFINIPATH_HWE_IBCBUSFRSPCPARITYERR) | ||
| 428 | strlcat(msg, "[IPATH2IB Parity]", msgl); | ||
| 429 | |||
| 430 | #define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP | \ | ||
| 431 | INFINIPATH_HWE_COREPLL_RFSLIP ) | ||
| 432 | |||
| 433 | if (hwerrs & _IPATH_PLL_FAIL) { | ||
| 434 | snprintf(bitsmsg, sizeof bitsmsg, | ||
| 435 | "[PLL failed (%llx), PE-800 unusable]", | ||
| 436 | (unsigned long long) hwerrs & _IPATH_PLL_FAIL); | ||
| 437 | strlcat(msg, bitsmsg, msgl); | ||
| 438 | /* ignore from now on, so disable until driver reloaded */ | ||
| 439 | dd->ipath_hwerrmask &= ~(hwerrs & _IPATH_PLL_FAIL); | ||
| 440 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 441 | dd->ipath_hwerrmask); | ||
| 442 | } | ||
| 443 | |||
| 444 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { | ||
| 445 | /* | ||
| 446 | * If it occurs, it is left masked since the eternal | ||
| 447 | * interface is unused | ||
| 448 | */ | ||
| 449 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; | ||
| 450 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, | ||
| 451 | dd->ipath_hwerrmask); | ||
| 452 | } | ||
| 453 | |||
| 454 | if (hwerrs & INFINIPATH_HWE_PCIEPOISONEDTLP) | ||
| 455 | strlcat(msg, "[PCIe Poisoned TLP]", msgl); | ||
| 456 | if (hwerrs & INFINIPATH_HWE_PCIECPLTIMEOUT) | ||
| 457 | strlcat(msg, "[PCIe completion timeout]", msgl); | ||
| 458 | |||
| 459 | /* | ||
| 460 | * In practice, it's unlikely wthat we'll see PCIe PLL, or bus | ||
| 461 | * parity or memory parity error failures, because most likely we | ||
| 462 | * won't be able to talk to the core of the chip. Nonetheless, we | ||
| 463 | * might see them, if they are in parts of the PCIe core that aren't | ||
| 464 | * essential. | ||
| 465 | */ | ||
| 466 | if (hwerrs & INFINIPATH_HWE_PCIE1PLLFAILED) | ||
| 467 | strlcat(msg, "[PCIePLL1]", msgl); | ||
| 468 | if (hwerrs & INFINIPATH_HWE_PCIE0PLLFAILED) | ||
| 469 | strlcat(msg, "[PCIePLL0]", msgl); | ||
| 470 | if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXTLH) | ||
| 471 | strlcat(msg, "[PCIe XTLH core parity]", msgl); | ||
| 472 | if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYXADM) | ||
| 473 | strlcat(msg, "[PCIe ADM TX core parity]", msgl); | ||
| 474 | if (hwerrs & INFINIPATH_HWE_PCIEBUSPARITYRADM) | ||
| 475 | strlcat(msg, "[PCIe ADM RX core parity]", msgl); | ||
| 476 | |||
| 477 | if (hwerrs & INFINIPATH_HWE_RXDSYNCMEMPARITYERR) | ||
| 478 | strlcat(msg, "[Rx Dsync]", msgl); | ||
| 479 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) | ||
| 480 | strlcat(msg, "[SerDes PLL]", msgl); | ||
| 481 | |||
| 482 | ipath_dev_err(dd, "%s hardware error\n", msg); | ||
| 483 | if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) { | ||
| 484 | /* | ||
| 485 | * for /sys status file ; if no trailing } is copied, we'll | ||
| 486 | * know it was truncated. | ||
| 487 | */ | ||
| 488 | snprintf(dd->ipath_freezemsg, dd->ipath_freezelen, | ||
| 489 | "{%s}", msg); | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | /** | ||
| 494 | * ipath_pe_boardname - fill in the board name | ||
| 495 | * @dd: the infinipath device | ||
| 496 | * @name: the output buffer | ||
| 497 | * @namelen: the size of the output buffer | ||
| 498 | * | ||
| 499 | * info is based on the board revision register | ||
| 500 | */ | ||
| 501 | static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, | ||
| 502 | size_t namelen) | ||
| 503 | { | ||
| 504 | char *n = NULL; | ||
| 505 | u8 boardrev = dd->ipath_boardrev; | ||
| 506 | int ret; | ||
| 507 | |||
| 508 | switch (boardrev) { | ||
| 509 | case 0: | ||
| 510 | n = "InfiniPath_Emulation"; | ||
| 511 | break; | ||
| 512 | case 1: | ||
| 513 | n = "InfiniPath_PE-800-Bringup"; | ||
| 514 | break; | ||
| 515 | case 2: | ||
| 516 | n = "InfiniPath_PE-880"; | ||
| 517 | break; | ||
| 518 | case 3: | ||
| 519 | n = "InfiniPath_PE-850"; | ||
| 520 | break; | ||
| 521 | case 4: | ||
| 522 | n = "InfiniPath_PE-860"; | ||
| 523 | break; | ||
| 524 | default: | ||
| 525 | ipath_dev_err(dd, | ||
| 526 | "Don't yet know about board with ID %u\n", | ||
| 527 | boardrev); | ||
| 528 | snprintf(name, namelen, "Unknown_InfiniPath_PE-8xx_%u", | ||
| 529 | boardrev); | ||
| 530 | break; | ||
| 531 | } | ||
| 532 | if (n) | ||
| 533 | snprintf(name, namelen, "%s", n); | ||
| 534 | |||
| 535 | if (dd->ipath_majrev != 4 || dd->ipath_minrev != 1) { | ||
| 536 | ipath_dev_err(dd, "Unsupported PE-800 revision %u.%u!\n", | ||
| 537 | dd->ipath_majrev, dd->ipath_minrev); | ||
| 538 | ret = 1; | ||
| 539 | } else | ||
| 540 | ret = 0; | ||
| 541 | |||
| 542 | return ret; | ||
| 543 | } | ||
| 544 | |||
| 545 | /** | ||
| 546 | * ipath_pe_init_hwerrors - enable hardware errors | ||
| 547 | * @dd: the infinipath device | ||
| 548 | * | ||
| 549 | * now that we have finished initializing everything that might reasonably | ||
| 550 | * cause a hardware error, and cleared those errors bits as they occur, | ||
| 551 | * we can enable hardware errors in the mask (potentially enabling | ||
| 552 | * freeze mode), and enable hardware errors as errors (along with | ||
| 553 | * everything else) in errormask | ||
| 554 | */ | ||
| 555 | void ipath_pe_init_hwerrors(struct ipath_devdata *dd) | ||
| 556 | { | ||
| 557 | ipath_err_t val; | ||
| 558 | u64 extsval; | ||
| 559 | |||
| 560 | extsval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); | ||
| 561 | |||
| 562 | if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST)) | ||
| 563 | ipath_dev_err(dd, "MemBIST did not complete!\n"); | ||
| 564 | |||
| 565 | val = ~0ULL; /* barring bugs, all hwerrors become interrupts, */ | ||
| 566 | |||
| 567 | if (!dd->ipath_boardrev) // no PLL for Emulator | ||
| 568 | val &= ~INFINIPATH_HWE_SERDESPLLFAILED; | ||
| 569 | |||
| 570 | /* workaround bug 9460 in internal interface bus parity checking */ | ||
| 571 | val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM; | ||
| 572 | |||
| 573 | dd->ipath_hwerrmask = val; | ||
| 574 | } | ||
| 575 | |||
| 576 | /** | ||
| 577 | * ipath_pe_bringup_serdes - bring up the serdes | ||
| 578 | * @dd: the infinipath device | ||
| 579 | */ | ||
| 580 | int ipath_pe_bringup_serdes(struct ipath_devdata *dd) | ||
| 581 | { | ||
| 582 | u64 val, tmp, config1; | ||
| 583 | int ret = 0, change = 0; | ||
| 584 | |||
| 585 | ipath_dbg("Trying to bringup serdes\n"); | ||
| 586 | |||
| 587 | if (ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus) & | ||
| 588 | INFINIPATH_HWE_SERDESPLLFAILED) { | ||
| 589 | ipath_dbg("At start, serdes PLL failed bit set " | ||
| 590 | "in hwerrstatus, clearing and continuing\n"); | ||
| 591 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | ||
| 592 | INFINIPATH_HWE_SERDESPLLFAILED); | ||
| 593 | } | ||
| 594 | |||
| 595 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 596 | config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1); | ||
| 597 | |||
| 598 | ipath_cdbg(VERBOSE, "SerDes status config0=%llx config1=%llx, " | ||
| 599 | "xgxsconfig %llx\n", (unsigned long long) val, | ||
| 600 | (unsigned long long) config1, (unsigned long long) | ||
| 601 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | ||
| 602 | |||
| 603 | /* | ||
| 604 | * Force reset on, also set rxdetect enable. Must do before reading | ||
| 605 | * serdesstatus at least for simulation, or some of the bits in | ||
| 606 | * serdes status will come back as undefined and cause simulation | ||
| 607 | * failures | ||
| 608 | */ | ||
| 609 | val |= INFINIPATH_SERDC0_RESET_PLL | INFINIPATH_SERDC0_RXDETECT_EN | ||
| 610 | | INFINIPATH_SERDC0_L1PWR_DN; | ||
| 611 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 612 | /* be sure chip saw it */ | ||
| 613 | tmp = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 614 | udelay(5); /* need pll reset set at least for a bit */ | ||
| 615 | /* | ||
| 616 | * after PLL is reset, set the per-lane Resets and TxIdle and | ||
| 617 | * clear the PLL reset and rxdetect (to get falling edge). | ||
| 618 | * Leave L1PWR bits set (permanently) | ||
| 619 | */ | ||
| 620 | val &= ~(INFINIPATH_SERDC0_RXDETECT_EN | INFINIPATH_SERDC0_RESET_PLL | ||
| 621 | | INFINIPATH_SERDC0_L1PWR_DN); | ||
| 622 | val |= INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE; | ||
| 623 | ipath_cdbg(VERBOSE, "Clearing pll reset and setting lane resets " | ||
| 624 | "and txidle (%llx)\n", (unsigned long long) val); | ||
| 625 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 626 | /* be sure chip saw it */ | ||
| 627 | tmp = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 628 | /* need PLL reset clear for at least 11 usec before lane | ||
| 629 | * resets cleared; give it a few more to be sure */ | ||
| 630 | udelay(15); | ||
| 631 | val &= ~(INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE); | ||
| 632 | |||
| 633 | ipath_cdbg(VERBOSE, "Clearing lane resets and txidle " | ||
| 634 | "(writing %llx)\n", (unsigned long long) val); | ||
| 635 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 636 | /* be sure chip saw it */ | ||
| 637 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 638 | |||
| 639 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | ||
| 640 | if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) & | ||
| 641 | INFINIPATH_XGXS_MDIOADDR_MASK) != 3) { | ||
| 642 | val &= | ||
| 643 | ~(INFINIPATH_XGXS_MDIOADDR_MASK << | ||
| 644 | INFINIPATH_XGXS_MDIOADDR_SHIFT); | ||
| 645 | /* MDIO address 3 */ | ||
| 646 | val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT; | ||
| 647 | change = 1; | ||
| 648 | } | ||
| 649 | if (val & INFINIPATH_XGXS_RESET) { | ||
| 650 | val &= ~INFINIPATH_XGXS_RESET; | ||
| 651 | change = 1; | ||
| 652 | } | ||
| 653 | if (change) | ||
| 654 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); | ||
| 655 | |||
| 656 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 657 | |||
| 658 | /* clear current and de-emphasis bits */ | ||
| 659 | config1 &= ~0x0ffffffff00ULL; | ||
| 660 | /* set current to 20ma */ | ||
| 661 | config1 |= 0x00000000000ULL; | ||
| 662 | /* set de-emphasis to -5.68dB */ | ||
| 663 | config1 |= 0x0cccc000000ULL; | ||
| 664 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig1, config1); | ||
| 665 | |||
| 666 | ipath_cdbg(VERBOSE, "done: SerDes status config0=%llx " | ||
| 667 | "config1=%llx, sstatus=%llx xgxs=%llx\n", | ||
| 668 | (unsigned long long) val, (unsigned long long) config1, | ||
| 669 | (unsigned long long) | ||
| 670 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesstatus), | ||
| 671 | (unsigned long long) | ||
| 672 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | ||
| 673 | |||
| 674 | if (!ipath_waitfor_mdio_cmdready(dd)) { | ||
| 675 | ipath_write_kreg( | ||
| 676 | dd, dd->ipath_kregs->kr_mdio, | ||
| 677 | ipath_mdio_req(IPATH_MDIO_CMD_READ, 31, | ||
| 678 | IPATH_MDIO_CTRL_XGXS_REG_8, 0)); | ||
| 679 | if (ipath_waitfor_complete(dd, dd->ipath_kregs->kr_mdio, | ||
| 680 | IPATH_MDIO_DATAVALID, &val)) | ||
| 681 | ipath_dbg("Never got MDIO data for XGXS " | ||
| 682 | "status read\n"); | ||
| 683 | else | ||
| 684 | ipath_cdbg(VERBOSE, "MDIO Read reg8, " | ||
| 685 | "'bank' 31 %x\n", (u32) val); | ||
| 686 | } else | ||
| 687 | ipath_dbg("Never got MDIO cmdready for XGXS status read\n"); | ||
| 688 | |||
| 689 | return ret; | ||
| 690 | } | ||
| 691 | |||
| 692 | /** | ||
| 693 | * ipath_pe_quiet_serdes - set serdes to txidle | ||
| 694 | * @dd: the infinipath device | ||
| 695 | * Called when driver is being unloaded | ||
| 696 | */ | ||
| 697 | void ipath_pe_quiet_serdes(struct ipath_devdata *dd) | ||
| 698 | { | ||
| 699 | u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | ||
| 700 | |||
| 701 | val |= INFINIPATH_SERDC0_TXIDLE; | ||
| 702 | ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n", | ||
| 703 | (unsigned long long) val); | ||
| 704 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | ||
| 705 | } | ||
| 706 | |||
| 707 | /* this is not yet needed on the PE800, so just return 0. */ | ||
| 708 | static int ipath_pe_intconfig(struct ipath_devdata *dd) | ||
| 709 | { | ||
| 710 | return 0; | ||
| 711 | } | ||
| 712 | |||
| 713 | /** | ||
| 714 | * ipath_setup_pe_setextled - set the state of the two external LEDs | ||
| 715 | * @dd: the infinipath device | ||
| 716 | * @lst: the L state | ||
| 717 | * @ltst: the LT state | ||
| 718 | |||
| 719 | * These LEDs indicate the physical and logical state of IB link. | ||
| 720 | * For this chip (at least with recommended board pinouts), LED1 | ||
| 721 | * is Yellow (logical state) and LED2 is Green (physical state), | ||
| 722 | * | ||
| 723 | * Note: We try to match the Mellanox HCA LED behavior as best | ||
| 724 | * we can. Green indicates physical link state is OK (something is | ||
| 725 | * plugged in, and we can train). | ||
| 726 | * Amber indicates the link is logically up (ACTIVE). | ||
| 727 | * Mellanox further blinks the amber LED to indicate data packet | ||
| 728 | * activity, but we have no hardware support for that, so it would | ||
| 729 | * require waking up every 10-20 msecs and checking the counters | ||
| 730 | * on the chip, and then turning the LED off if appropriate. That's | ||
| 731 | * visible overhead, so not something we will do. | ||
| 732 | * | ||
| 733 | */ | ||
| 734 | static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst, | ||
| 735 | u64 ltst) | ||
| 736 | { | ||
| 737 | u64 extctl; | ||
| 738 | |||
| 739 | /* the diags use the LED to indicate diag info, so we leave | ||
| 740 | * the external LED alone when the diags are running */ | ||
| 741 | if (ipath_diag_inuse) | ||
| 742 | return; | ||
| 743 | |||
| 744 | extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON | | ||
| 745 | INFINIPATH_EXTC_LED2PRIPORT_ON); | ||
| 746 | |||
| 747 | if (ltst & INFINIPATH_IBCS_LT_STATE_LINKUP) | ||
| 748 | extctl |= INFINIPATH_EXTC_LED2PRIPORT_ON; | ||
| 749 | if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE) | ||
| 750 | extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON; | ||
| 751 | dd->ipath_extctrl = extctl; | ||
| 752 | ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl); | ||
| 753 | } | ||
| 754 | |||
| 755 | /** | ||
| 756 | * ipath_setup_pe_cleanup - clean up any per-chip chip-specific stuff | ||
| 757 | * @dd: the infinipath device | ||
| 758 | * | ||
| 759 | * This is called during driver unload. | ||
| 760 | * We do the pci_disable_msi here, not in generic code, because it | ||
| 761 | * isn't used for the HT-400. If we do end up needing pci_enable_msi | ||
| 762 | * at some point in the future for HT-400, we'll move the call back | ||
| 763 | * into the main init_one code. | ||
| 764 | */ | ||
| 765 | static void ipath_setup_pe_cleanup(struct ipath_devdata *dd) | ||
| 766 | { | ||
| 767 | dd->ipath_msi_lo = 0; /* just in case unload fails */ | ||
| 768 | pci_disable_msi(dd->pcidev); | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * ipath_setup_pe_config - setup PCIe config related stuff | ||
| 773 | * @dd: the infinipath device | ||
| 774 | * @pdev: the PCI device | ||
| 775 | * | ||
| 776 | * The pci_enable_msi() call will fail on systems with MSI quirks | ||
| 777 | * such as those with AMD8131, even if the device of interest is not | ||
| 778 | * attached to that device, (in the 2.6.13 - 2.6.15 kernels, at least, fixed | ||
| 779 | * late in 2.6.16). | ||
| 780 | * All that can be done is to edit the kernel source to remove the quirk | ||
| 781 | * check until that is fixed. | ||
| 782 | * We do not need to call enable_msi() for our HyperTransport chip (HT-400), | ||
| 783 | * even those it uses MSI, and we want to avoid the quirk warning, so | ||
| 784 | * So we call enable_msi only for the PE-800. If we do end up needing | ||
| 785 | * pci_enable_msi at some point in the future for HT-400, we'll move the | ||
| 786 | * call back into the main init_one code. | ||
| 787 | * We save the msi lo and hi values, so we can restore them after | ||
| 788 | * chip reset (the kernel PCI infrastructure doesn't yet handle that | ||
| 789 | * correctly). | ||
| 790 | */ | ||
| 791 | static int ipath_setup_pe_config(struct ipath_devdata *dd, | ||
| 792 | struct pci_dev *pdev) | ||
| 793 | { | ||
| 794 | int pos, ret; | ||
| 795 | |||
| 796 | dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ | ||
| 797 | ret = pci_enable_msi(dd->pcidev); | ||
| 798 | if (ret) | ||
| 799 | ipath_dev_err(dd, "pci_enable_msi failed: %d, " | ||
| 800 | "interrupts may not work\n", ret); | ||
| 801 | /* continue even if it fails, we may still be OK... */ | ||
| 802 | |||
| 803 | if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) { | ||
| 804 | u16 control; | ||
| 805 | pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, | ||
| 806 | &dd->ipath_msi_lo); | ||
| 807 | pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, | ||
| 808 | &dd->ipath_msi_hi); | ||
| 809 | pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, | ||
| 810 | &control); | ||
| 811 | /* now save the data (vector) info */ | ||
| 812 | pci_read_config_word(dd->pcidev, | ||
| 813 | pos + ((control & PCI_MSI_FLAGS_64BIT) | ||
| 814 | ? 12 : 8), | ||
| 815 | &dd->ipath_msi_data); | ||
| 816 | ipath_cdbg(VERBOSE, "Read msi data 0x%x from config offset " | ||
| 817 | "0x%x, control=0x%x\n", dd->ipath_msi_data, | ||
| 818 | pos + ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), | ||
| 819 | control); | ||
| 820 | /* we save the cachelinesize also, although it doesn't | ||
| 821 | * really matter */ | ||
| 822 | pci_read_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, | ||
| 823 | &dd->ipath_pci_cacheline); | ||
| 824 | } else | ||
| 825 | ipath_dev_err(dd, "Can't find MSI capability, " | ||
| 826 | "can't save MSI settings for reset\n"); | ||
| 827 | if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP))) { | ||
| 828 | u16 linkstat; | ||
| 829 | pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA, | ||
| 830 | &linkstat); | ||
| 831 | linkstat >>= 4; | ||
| 832 | linkstat &= 0x1f; | ||
| 833 | if (linkstat != 8) | ||
| 834 | ipath_dev_err(dd, "PCIe width %u, " | ||
| 835 | "performance reduced\n", linkstat); | ||
| 836 | } | ||
| 837 | else | ||
| 838 | ipath_dev_err(dd, "Can't find PCI Express " | ||
| 839 | "capability!\n"); | ||
| 840 | return 0; | ||
| 841 | } | ||
| 842 | |||
| 843 | static void ipath_init_pe_variables(void) | ||
| 844 | { | ||
| 845 | /* | ||
| 846 | * bits for selecting i2c direction and values, | ||
| 847 | * used for I2C serial flash | ||
| 848 | */ | ||
| 849 | ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; | ||
| 850 | ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; | ||
| 851 | ipath_gpio_sda = IPATH_GPIO_SDA; | ||
| 852 | ipath_gpio_scl = IPATH_GPIO_SCL; | ||
| 853 | |||
| 854 | /* variables for sanity checking interrupt and errors */ | ||
| 855 | infinipath_hwe_bitsextant = | ||
| 856 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | ||
| 857 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | | ||
| 858 | (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK << | ||
| 859 | INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) | | ||
| 860 | INFINIPATH_HWE_PCIE1PLLFAILED | | ||
| 861 | INFINIPATH_HWE_PCIE0PLLFAILED | | ||
| 862 | INFINIPATH_HWE_PCIEPOISONEDTLP | | ||
| 863 | INFINIPATH_HWE_PCIECPLTIMEOUT | | ||
| 864 | INFINIPATH_HWE_PCIEBUSPARITYXTLH | | ||
| 865 | INFINIPATH_HWE_PCIEBUSPARITYXADM | | ||
| 866 | INFINIPATH_HWE_PCIEBUSPARITYRADM | | ||
| 867 | INFINIPATH_HWE_MEMBISTFAILED | | ||
| 868 | INFINIPATH_HWE_COREPLL_FBSLIP | | ||
| 869 | INFINIPATH_HWE_COREPLL_RFSLIP | | ||
| 870 | INFINIPATH_HWE_SERDESPLLFAILED | | ||
| 871 | INFINIPATH_HWE_IBCBUSTOSPCPARITYERR | | ||
| 872 | INFINIPATH_HWE_IBCBUSFRSPCPARITYERR; | ||
| 873 | infinipath_i_bitsextant = | ||
| 874 | (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | | ||
| 875 | (INFINIPATH_I_RCVAVAIL_MASK << | ||
| 876 | INFINIPATH_I_RCVAVAIL_SHIFT) | | ||
| 877 | INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT | | ||
| 878 | INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO; | ||
| 879 | infinipath_e_bitsextant = | ||
| 880 | INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC | | ||
| 881 | INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN | | ||
| 882 | INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN | | ||
| 883 | INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RUNEXPCHAR | | ||
| 884 | INFINIPATH_E_RUNSUPVL | INFINIPATH_E_REBP | | ||
| 885 | INFINIPATH_E_RIBFLOW | INFINIPATH_E_RBADVERSION | | ||
| 886 | INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | | ||
| 887 | INFINIPATH_E_RBADTID | INFINIPATH_E_RHDRLEN | | ||
| 888 | INFINIPATH_E_RHDR | INFINIPATH_E_RIBLOSTLINK | | ||
| 889 | INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SMAXPKTLEN | | ||
| 890 | INFINIPATH_E_SUNDERRUN | INFINIPATH_E_SPKTLEN | | ||
| 891 | INFINIPATH_E_SDROPPEDSMPPKT | INFINIPATH_E_SDROPPEDDATAPKT | | ||
| 892 | INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | | ||
| 893 | INFINIPATH_E_SUNSUPVL | INFINIPATH_E_IBSTATUSCHANGED | | ||
| 894 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET | | ||
| 895 | INFINIPATH_E_HARDWARE; | ||
| 896 | |||
| 897 | infinipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | ||
| 898 | infinipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | ||
| 899 | } | ||
| 900 | |||
| 901 | /* setup the MSI stuff again after a reset. I'd like to just call | ||
| 902 | * pci_enable_msi() and request_irq() again, but when I do that, | ||
| 903 | * the MSI enable bit doesn't get set in the command word, and | ||
| 904 | * we switch to to a different interrupt vector, which is confusing, | ||
| 905 | * so I instead just do it all inline. Perhaps somehow can tie this | ||
| 906 | * into the PCIe hotplug support at some point | ||
| 907 | * Note, because I'm doing it all here, I don't call pci_disable_msi() | ||
| 908 | * or free_irq() at the start of ipath_setup_pe_reset(). | ||
| 909 | */ | ||
| 910 | static int ipath_reinit_msi(struct ipath_devdata *dd) | ||
| 911 | { | ||
| 912 | int pos; | ||
| 913 | u16 control; | ||
| 914 | int ret; | ||
| 915 | |||
| 916 | if (!dd->ipath_msi_lo) { | ||
| 917 | dev_info(&dd->pcidev->dev, "Can't restore MSI config, " | ||
| 918 | "initial setup failed?\n"); | ||
| 919 | ret = 0; | ||
| 920 | goto bail; | ||
| 921 | } | ||
| 922 | |||
| 923 | if (!(pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) { | ||
| 924 | ipath_dev_err(dd, "Can't find MSI capability, " | ||
| 925 | "can't restore MSI settings\n"); | ||
| 926 | ret = 0; | ||
| 927 | goto bail; | ||
| 928 | } | ||
| 929 | ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", | ||
| 930 | dd->ipath_msi_lo, pos + PCI_MSI_ADDRESS_LO); | ||
| 931 | pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, | ||
| 932 | dd->ipath_msi_lo); | ||
| 933 | ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", | ||
| 934 | dd->ipath_msi_hi, pos + PCI_MSI_ADDRESS_HI); | ||
| 935 | pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, | ||
| 936 | dd->ipath_msi_hi); | ||
| 937 | pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, &control); | ||
| 938 | if (!(control & PCI_MSI_FLAGS_ENABLE)) { | ||
| 939 | ipath_cdbg(VERBOSE, "MSI control at off %x was %x, " | ||
| 940 | "setting MSI enable (%x)\n", pos + PCI_MSI_FLAGS, | ||
| 941 | control, control | PCI_MSI_FLAGS_ENABLE); | ||
| 942 | control |= PCI_MSI_FLAGS_ENABLE; | ||
| 943 | pci_write_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, | ||
| 944 | control); | ||
| 945 | } | ||
| 946 | /* now rewrite the data (vector) info */ | ||
| 947 | pci_write_config_word(dd->pcidev, pos + | ||
| 948 | ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), | ||
| 949 | dd->ipath_msi_data); | ||
| 950 | /* we restore the cachelinesize also, although it doesn't really | ||
| 951 | * matter */ | ||
| 952 | pci_write_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, | ||
| 953 | dd->ipath_pci_cacheline); | ||
| 954 | /* and now set the pci master bit again */ | ||
| 955 | pci_set_master(dd->pcidev); | ||
| 956 | ret = 1; | ||
| 957 | |||
| 958 | bail: | ||
| 959 | return ret; | ||
| 960 | } | ||
| 961 | |||
| 962 | /* This routine sleeps, so it can only be called from user context, not | ||
| 963 | * from interrupt context. If we need interrupt context, we can split | ||
| 964 | * it into two routines. | ||
| 965 | */ | ||
| 966 | static int ipath_setup_pe_reset(struct ipath_devdata *dd) | ||
| 967 | { | ||
| 968 | u64 val; | ||
| 969 | int i; | ||
| 970 | int ret; | ||
| 971 | |||
| 972 | /* Use ERROR so it shows up in logs, etc. */ | ||
| 973 | ipath_dev_err(dd, "Resetting PE-800 unit %u\n", | ||
| 974 | dd->ipath_unit); | ||
| 975 | val = dd->ipath_control | INFINIPATH_C_RESET; | ||
| 976 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val); | ||
| 977 | mb(); | ||
| 978 | |||
| 979 | for (i = 1; i <= 5; i++) { | ||
| 980 | int r; | ||
| 981 | /* allow MBIST, etc. to complete; longer on each retry. | ||
| 982 | * We sometimes get machine checks from bus timeout if no | ||
| 983 | * response, so for now, make it *really* long. | ||
| 984 | */ | ||
| 985 | msleep(1000 + (1 + i) * 2000); | ||
| 986 | if ((r = | ||
| 987 | pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, | ||
| 988 | dd->ipath_pcibar0))) | ||
| 989 | ipath_dev_err(dd, "rewrite of BAR0 failed: %d\n", | ||
| 990 | r); | ||
| 991 | if ((r = | ||
| 992 | pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, | ||
| 993 | dd->ipath_pcibar1))) | ||
| 994 | ipath_dev_err(dd, "rewrite of BAR1 failed: %d\n", | ||
| 995 | r); | ||
| 996 | /* now re-enable memory access */ | ||
| 997 | if ((r = pci_enable_device(dd->pcidev))) | ||
| 998 | ipath_dev_err(dd, "pci_enable_device failed after " | ||
| 999 | "reset: %d\n", r); | ||
| 1000 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); | ||
| 1001 | if (val == dd->ipath_revision) { | ||
| 1002 | ipath_cdbg(VERBOSE, "Got matching revision " | ||
| 1003 | "register %llx on try %d\n", | ||
| 1004 | (unsigned long long) val, i); | ||
| 1005 | ret = ipath_reinit_msi(dd); | ||
| 1006 | goto bail; | ||
| 1007 | } | ||
| 1008 | /* Probably getting -1 back */ | ||
| 1009 | ipath_dbg("Didn't get expected revision register, " | ||
| 1010 | "got %llx, try %d\n", (unsigned long long) val, | ||
| 1011 | i + 1); | ||
| 1012 | } | ||
| 1013 | ret = 0; /* failed */ | ||
| 1014 | |||
| 1015 | bail: | ||
| 1016 | return ret; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | /** | ||
| 1020 | * ipath_pe_put_tid - write a TID in chip | ||
| 1021 | * @dd: the infinipath device | ||
| 1022 | * @tidptr: pointer to the expected TID (in chip) to udpate | ||
| 1023 | * @tidtype: 0 for eager, 1 for expected | ||
| 1024 | * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing | ||
| 1025 | * | ||
| 1026 | * This exists as a separate routine to allow for special locking etc. | ||
| 1027 | * It's used for both the full cleanup on exit, as well as the normal | ||
| 1028 | * setup and teardown. | ||
| 1029 | */ | ||
| 1030 | static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, | ||
| 1031 | u32 type, unsigned long pa) | ||
| 1032 | { | ||
| 1033 | u32 __iomem *tidp32 = (u32 __iomem *)tidptr; | ||
| 1034 | unsigned long flags = 0; /* keep gcc quiet */ | ||
| 1035 | |||
| 1036 | if (pa != dd->ipath_tidinvalid) { | ||
| 1037 | if (pa & ((1U << 11) - 1)) { | ||
| 1038 | dev_info(&dd->pcidev->dev, "BUG: physaddr %lx " | ||
| 1039 | "not 4KB aligned!\n", pa); | ||
| 1040 | return; | ||
| 1041 | } | ||
| 1042 | pa >>= 11; | ||
| 1043 | /* paranoia check */ | ||
| 1044 | if (pa & (7<<29)) | ||
| 1045 | ipath_dev_err(dd, | ||
| 1046 | "BUG: Physical page address 0x%lx " | ||
| 1047 | "has bits set in 31-29\n", pa); | ||
| 1048 | |||
| 1049 | if (type == 0) | ||
| 1050 | pa |= dd->ipath_tidtemplate; | ||
| 1051 | else /* for now, always full 4KB page */ | ||
| 1052 | pa |= 2 << 29; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | /* workaround chip bug 9437 by writing each TID twice | ||
| 1056 | * and holding a spinlock around the writes, so they don't | ||
| 1057 | * intermix with other TID (eager or expected) writes | ||
| 1058 | * Unfortunately, this call can be done from interrupt level | ||
| 1059 | * for the port 0 eager TIDs, so we have to use irqsave | ||
| 1060 | */ | ||
| 1061 | spin_lock_irqsave(&dd->ipath_tid_lock, flags); | ||
| 1062 | ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xfeeddeaf); | ||
| 1063 | if (dd->ipath_kregbase) | ||
| 1064 | writel(pa, tidp32); | ||
| 1065 | ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xdeadbeef); | ||
| 1066 | mmiowb(); | ||
| 1067 | spin_unlock_irqrestore(&dd->ipath_tid_lock, flags); | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /** | ||
| 1071 | * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager | ||
| 1072 | * @dd: the infinipath device | ||
| 1073 | * @port: the port | ||
| 1074 | * | ||
| 1075 | * clear all TID entries for a port, expected and eager. | ||
| 1076 | * Used from ipath_close(). On PE800, TIDs are only 32 bits, | ||
| 1077 | * not 64, but they are still on 64 bit boundaries, so tidbase | ||
| 1078 | * is declared as u64 * for the pointer math, even though we write 32 bits | ||
| 1079 | */ | ||
| 1080 | static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) | ||
| 1081 | { | ||
| 1082 | u64 __iomem *tidbase; | ||
| 1083 | unsigned long tidinv; | ||
| 1084 | int i; | ||
| 1085 | |||
| 1086 | if (!dd->ipath_kregbase) | ||
| 1087 | return; | ||
| 1088 | |||
| 1089 | ipath_cdbg(VERBOSE, "Invalidate TIDs for port %u\n", port); | ||
| 1090 | |||
| 1091 | tidinv = dd->ipath_tidinvalid; | ||
| 1092 | tidbase = (u64 __iomem *) | ||
| 1093 | ((char __iomem *)(dd->ipath_kregbase) + | ||
| 1094 | dd->ipath_rcvtidbase + | ||
| 1095 | port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); | ||
| 1096 | |||
| 1097 | for (i = 0; i < dd->ipath_rcvtidcnt; i++) | ||
| 1098 | ipath_pe_put_tid(dd, &tidbase[i], 0, tidinv); | ||
| 1099 | |||
| 1100 | tidbase = (u64 __iomem *) | ||
| 1101 | ((char __iomem *)(dd->ipath_kregbase) + | ||
| 1102 | dd->ipath_rcvegrbase + | ||
| 1103 | port * dd->ipath_rcvegrcnt * sizeof(*tidbase)); | ||
| 1104 | |||
| 1105 | for (i = 0; i < dd->ipath_rcvegrcnt; i++) | ||
| 1106 | ipath_pe_put_tid(dd, &tidbase[i], 1, tidinv); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /** | ||
| 1110 | * ipath_pe_tidtemplate - setup constants for TID updates | ||
| 1111 | * @dd: the infinipath device | ||
| 1112 | * | ||
| 1113 | * We setup stuff that we use a lot, to avoid calculating each time | ||
| 1114 | */ | ||
| 1115 | static void ipath_pe_tidtemplate(struct ipath_devdata *dd) | ||
| 1116 | { | ||
| 1117 | u32 egrsize = dd->ipath_rcvegrbufsize; | ||
| 1118 | |||
| 1119 | /* For now, we always allocate 4KB buffers (at init) so we can | ||
| 1120 | * receive max size packets. We may want a module parameter to | ||
| 1121 | * specify 2KB or 4KB and/or make be per port instead of per device | ||
| 1122 | * for those who want to reduce memory footprint. Note that the | ||
| 1123 | * ipath_rcvhdrentsize size must be large enough to hold the largest | ||
| 1124 | * IB header (currently 96 bytes) that we expect to handle (plus of | ||
| 1125 | * course the 2 dwords of RHF). | ||
| 1126 | */ | ||
| 1127 | if (egrsize == 2048) | ||
| 1128 | dd->ipath_tidtemplate = 1U << 29; | ||
| 1129 | else if (egrsize == 4096) | ||
| 1130 | dd->ipath_tidtemplate = 2U << 29; | ||
| 1131 | else { | ||
| 1132 | egrsize = 4096; | ||
| 1133 | dev_info(&dd->pcidev->dev, "BUG: unsupported egrbufsize " | ||
| 1134 | "%u, using %u\n", dd->ipath_rcvegrbufsize, | ||
| 1135 | egrsize); | ||
| 1136 | dd->ipath_tidtemplate = 2U << 29; | ||
| 1137 | } | ||
| 1138 | dd->ipath_tidinvalid = 0; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | static int ipath_pe_early_init(struct ipath_devdata *dd) | ||
| 1142 | { | ||
| 1143 | dd->ipath_flags |= IPATH_4BYTE_TID; | ||
| 1144 | |||
| 1145 | /* | ||
| 1146 | * For openib, we need to be able to handle an IB header of 96 bytes | ||
| 1147 | * or 24 dwords. HT-400 has arbitrary sized receive buffers, so we | ||
| 1148 | * made them the same size as the PIO buffers. The PE-800 does not | ||
| 1149 | * handle arbitrary size buffers, so we need the header large enough | ||
| 1150 | * to handle largest IB header, but still have room for a 2KB MTU | ||
| 1151 | * standard IB packet. | ||
| 1152 | */ | ||
| 1153 | dd->ipath_rcvhdrentsize = 24; | ||
| 1154 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; | ||
| 1155 | |||
| 1156 | /* For HT-400, we allocate a somewhat overly large eager buffer, | ||
| 1157 | * such that we can guarantee that we can receive the largest packet | ||
| 1158 | * that we can send out. To truly support a 4KB MTU, we need to | ||
| 1159 | * bump this to a larger value. We'll do this when I get around to | ||
| 1160 | * testing 4KB sends on the PE-800, which I have not yet done. | ||
| 1161 | */ | ||
| 1162 | dd->ipath_rcvegrbufsize = 2048; | ||
| 1163 | /* | ||
| 1164 | * the min() check here is currently a nop, but it may not always | ||
| 1165 | * be, depending on just how we do ipath_rcvegrbufsize | ||
| 1166 | */ | ||
| 1167 | dd->ipath_ibmaxlen = min(dd->ipath_piosize2k, | ||
| 1168 | dd->ipath_rcvegrbufsize + | ||
| 1169 | (dd->ipath_rcvhdrentsize << 2)); | ||
| 1170 | dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen; | ||
| 1171 | |||
| 1172 | /* | ||
| 1173 | * For PE-800, we can request a receive interrupt for 1 or | ||
| 1174 | * more packets from current offset. For now, we set this | ||
| 1175 | * up for a single packet, to match the HT-400 behavior. | ||
| 1176 | */ | ||
| 1177 | dd->ipath_rhdrhead_intr_off = 1ULL<<32; | ||
| 1178 | |||
| 1179 | return 0; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | int __attribute__((weak)) ipath_unordered_wc(void) | ||
| 1183 | { | ||
| 1184 | return 0; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | /** | ||
| 1188 | * ipath_init_pe_get_base_info - set chip-specific flags for user code | ||
| 1189 | * @dd: the infinipath device | ||
| 1190 | * @kbase: ipath_base_info pointer | ||
| 1191 | * | ||
| 1192 | * We set the PCIE flag because the lower bandwidth on PCIe vs | ||
| 1193 | * HyperTransport can affect some user packet algorithims. | ||
| 1194 | */ | ||
| 1195 | static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase) | ||
| 1196 | { | ||
| 1197 | struct ipath_base_info *kinfo = kbase; | ||
| 1198 | |||
| 1199 | if (ipath_unordered_wc()) { | ||
| 1200 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER; | ||
| 1201 | ipath_cdbg(PROC, "Intel processor, forcing WC order\n"); | ||
| 1202 | } | ||
| 1203 | else | ||
| 1204 | ipath_cdbg(PROC, "Not Intel processor, WC ordered\n"); | ||
| 1205 | |||
| 1206 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE; | ||
| 1207 | |||
| 1208 | return 0; | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | /** | ||
| 1212 | * ipath_init_pe800_funcs - set up the chip-specific function pointers | ||
| 1213 | * @dd: the infinipath device | ||
| 1214 | * | ||
| 1215 | * This is global, and is called directly at init to set up the | ||
| 1216 | * chip-specific function pointers for later use. | ||
| 1217 | */ | ||
| 1218 | void ipath_init_pe800_funcs(struct ipath_devdata *dd) | ||
| 1219 | { | ||
| 1220 | dd->ipath_f_intrsetup = ipath_pe_intconfig; | ||
| 1221 | dd->ipath_f_bus = ipath_setup_pe_config; | ||
| 1222 | dd->ipath_f_reset = ipath_setup_pe_reset; | ||
| 1223 | dd->ipath_f_get_boardname = ipath_pe_boardname; | ||
| 1224 | dd->ipath_f_init_hwerrors = ipath_pe_init_hwerrors; | ||
| 1225 | dd->ipath_f_early_init = ipath_pe_early_init; | ||
| 1226 | dd->ipath_f_handle_hwerrors = ipath_pe_handle_hwerrors; | ||
| 1227 | dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; | ||
| 1228 | dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; | ||
| 1229 | dd->ipath_f_clear_tids = ipath_pe_clear_tids; | ||
| 1230 | dd->ipath_f_put_tid = ipath_pe_put_tid; | ||
| 1231 | dd->ipath_f_cleanup = ipath_setup_pe_cleanup; | ||
| 1232 | dd->ipath_f_setextled = ipath_setup_pe_setextled; | ||
| 1233 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; | ||
| 1234 | |||
| 1235 | /* initialize chip-specific variables */ | ||
| 1236 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; | ||
| 1237 | |||
| 1238 | /* | ||
| 1239 | * setup the register offsets, since they are different for each | ||
| 1240 | * chip | ||
| 1241 | */ | ||
| 1242 | dd->ipath_kregs = &ipath_pe_kregs; | ||
| 1243 | dd->ipath_cregs = &ipath_pe_cregs; | ||
| 1244 | |||
| 1245 | ipath_init_pe_variables(); | ||
| 1246 | } | ||
| 1247 | |||
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c new file mode 100644 index 000000000000..6058d70d7577 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_qp.c | |||
| @@ -0,0 +1,913 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/err.h> | ||
| 34 | #include <linux/vmalloc.h> | ||
| 35 | |||
| 36 | #include "ipath_verbs.h" | ||
| 37 | #include "ips_common.h" | ||
| 38 | |||
| 39 | #define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) | ||
| 40 | #define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) | ||
| 41 | #define mk_qpn(qpt, map, off) (((map) - (qpt)->map) * BITS_PER_PAGE + \ | ||
| 42 | (off)) | ||
| 43 | #define find_next_offset(map, off) find_next_zero_bit((map)->page, \ | ||
| 44 | BITS_PER_PAGE, off) | ||
| 45 | |||
| 46 | #define TRANS_INVALID 0 | ||
| 47 | #define TRANS_ANY2RST 1 | ||
| 48 | #define TRANS_RST2INIT 2 | ||
| 49 | #define TRANS_INIT2INIT 3 | ||
| 50 | #define TRANS_INIT2RTR 4 | ||
| 51 | #define TRANS_RTR2RTS 5 | ||
| 52 | #define TRANS_RTS2RTS 6 | ||
| 53 | #define TRANS_SQERR2RTS 7 | ||
| 54 | #define TRANS_ANY2ERR 8 | ||
| 55 | #define TRANS_RTS2SQD 9 /* XXX Wait for expected ACKs & signal event */ | ||
| 56 | #define TRANS_SQD2SQD 10 /* error if not drained & parameter change */ | ||
| 57 | #define TRANS_SQD2RTS 11 /* error if not drained */ | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Convert the AETH credit code into the number of credits. | ||
| 61 | */ | ||
| 62 | static u32 credit_table[31] = { | ||
| 63 | 0, /* 0 */ | ||
| 64 | 1, /* 1 */ | ||
| 65 | 2, /* 2 */ | ||
| 66 | 3, /* 3 */ | ||
| 67 | 4, /* 4 */ | ||
| 68 | 6, /* 5 */ | ||
| 69 | 8, /* 6 */ | ||
| 70 | 12, /* 7 */ | ||
| 71 | 16, /* 8 */ | ||
| 72 | 24, /* 9 */ | ||
| 73 | 32, /* A */ | ||
| 74 | 48, /* B */ | ||
| 75 | 64, /* C */ | ||
| 76 | 96, /* D */ | ||
| 77 | 128, /* E */ | ||
| 78 | 192, /* F */ | ||
| 79 | 256, /* 10 */ | ||
| 80 | 384, /* 11 */ | ||
| 81 | 512, /* 12 */ | ||
| 82 | 768, /* 13 */ | ||
| 83 | 1024, /* 14 */ | ||
| 84 | 1536, /* 15 */ | ||
| 85 | 2048, /* 16 */ | ||
| 86 | 3072, /* 17 */ | ||
| 87 | 4096, /* 18 */ | ||
| 88 | 6144, /* 19 */ | ||
| 89 | 8192, /* 1A */ | ||
| 90 | 12288, /* 1B */ | ||
| 91 | 16384, /* 1C */ | ||
| 92 | 24576, /* 1D */ | ||
| 93 | 32768 /* 1E */ | ||
| 94 | }; | ||
| 95 | |||
| 96 | static u32 alloc_qpn(struct ipath_qp_table *qpt) | ||
| 97 | { | ||
| 98 | u32 i, offset, max_scan, qpn; | ||
| 99 | struct qpn_map *map; | ||
| 100 | u32 ret; | ||
| 101 | |||
| 102 | qpn = qpt->last + 1; | ||
| 103 | if (qpn >= QPN_MAX) | ||
| 104 | qpn = 2; | ||
| 105 | offset = qpn & BITS_PER_PAGE_MASK; | ||
| 106 | map = &qpt->map[qpn / BITS_PER_PAGE]; | ||
| 107 | max_scan = qpt->nmaps - !offset; | ||
| 108 | for (i = 0;;) { | ||
| 109 | if (unlikely(!map->page)) { | ||
| 110 | unsigned long page = get_zeroed_page(GFP_KERNEL); | ||
| 111 | unsigned long flags; | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Free the page if someone raced with us | ||
| 115 | * installing it: | ||
| 116 | */ | ||
| 117 | spin_lock_irqsave(&qpt->lock, flags); | ||
| 118 | if (map->page) | ||
| 119 | free_page(page); | ||
| 120 | else | ||
| 121 | map->page = (void *)page; | ||
| 122 | spin_unlock_irqrestore(&qpt->lock, flags); | ||
| 123 | if (unlikely(!map->page)) | ||
| 124 | break; | ||
| 125 | } | ||
| 126 | if (likely(atomic_read(&map->n_free))) { | ||
| 127 | do { | ||
| 128 | if (!test_and_set_bit(offset, map->page)) { | ||
| 129 | atomic_dec(&map->n_free); | ||
| 130 | qpt->last = qpn; | ||
| 131 | ret = qpn; | ||
| 132 | goto bail; | ||
| 133 | } | ||
| 134 | offset = find_next_offset(map, offset); | ||
| 135 | qpn = mk_qpn(qpt, map, offset); | ||
| 136 | /* | ||
| 137 | * This test differs from alloc_pidmap(). | ||
| 138 | * If find_next_offset() does find a zero | ||
| 139 | * bit, we don't need to check for QPN | ||
| 140 | * wrapping around past our starting QPN. | ||
| 141 | * We just need to be sure we don't loop | ||
| 142 | * forever. | ||
| 143 | */ | ||
| 144 | } while (offset < BITS_PER_PAGE && qpn < QPN_MAX); | ||
| 145 | } | ||
| 146 | /* | ||
| 147 | * In order to keep the number of pages allocated to a | ||
| 148 | * minimum, we scan the all existing pages before increasing | ||
| 149 | * the size of the bitmap table. | ||
| 150 | */ | ||
| 151 | if (++i > max_scan) { | ||
| 152 | if (qpt->nmaps == QPNMAP_ENTRIES) | ||
| 153 | break; | ||
| 154 | map = &qpt->map[qpt->nmaps++]; | ||
| 155 | offset = 0; | ||
| 156 | } else if (map < &qpt->map[qpt->nmaps]) { | ||
| 157 | ++map; | ||
| 158 | offset = 0; | ||
| 159 | } else { | ||
| 160 | map = &qpt->map[0]; | ||
| 161 | offset = 2; | ||
| 162 | } | ||
| 163 | qpn = mk_qpn(qpt, map, offset); | ||
| 164 | } | ||
| 165 | |||
| 166 | ret = 0; | ||
| 167 | |||
| 168 | bail: | ||
| 169 | return ret; | ||
| 170 | } | ||
| 171 | |||
| 172 | static void free_qpn(struct ipath_qp_table *qpt, u32 qpn) | ||
| 173 | { | ||
| 174 | struct qpn_map *map; | ||
| 175 | |||
| 176 | map = qpt->map + qpn / BITS_PER_PAGE; | ||
| 177 | if (map->page) | ||
| 178 | clear_bit(qpn & BITS_PER_PAGE_MASK, map->page); | ||
| 179 | atomic_inc(&map->n_free); | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * ipath_alloc_qpn - allocate a QP number | ||
| 184 | * @qpt: the QP table | ||
| 185 | * @qp: the QP | ||
| 186 | * @type: the QP type (IB_QPT_SMI and IB_QPT_GSI are special) | ||
| 187 | * | ||
| 188 | * Allocate the next available QPN and put the QP into the hash table. | ||
| 189 | * The hash table holds a reference to the QP. | ||
| 190 | */ | ||
| 191 | int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp, | ||
| 192 | enum ib_qp_type type) | ||
| 193 | { | ||
| 194 | unsigned long flags; | ||
| 195 | u32 qpn; | ||
| 196 | int ret; | ||
| 197 | |||
| 198 | if (type == IB_QPT_SMI) | ||
| 199 | qpn = 0; | ||
| 200 | else if (type == IB_QPT_GSI) | ||
| 201 | qpn = 1; | ||
| 202 | else { | ||
| 203 | /* Allocate the next available QPN */ | ||
| 204 | qpn = alloc_qpn(qpt); | ||
| 205 | if (qpn == 0) { | ||
| 206 | ret = -ENOMEM; | ||
| 207 | goto bail; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | qp->ibqp.qp_num = qpn; | ||
| 211 | |||
| 212 | /* Add the QP to the hash table. */ | ||
| 213 | spin_lock_irqsave(&qpt->lock, flags); | ||
| 214 | |||
| 215 | qpn %= qpt->max; | ||
| 216 | qp->next = qpt->table[qpn]; | ||
| 217 | qpt->table[qpn] = qp; | ||
| 218 | atomic_inc(&qp->refcount); | ||
| 219 | |||
| 220 | spin_unlock_irqrestore(&qpt->lock, flags); | ||
| 221 | ret = 0; | ||
| 222 | |||
| 223 | bail: | ||
| 224 | return ret; | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * ipath_free_qp - remove a QP from the QP table | ||
| 229 | * @qpt: the QP table | ||
| 230 | * @qp: the QP to remove | ||
| 231 | * | ||
| 232 | * Remove the QP from the table so it can't be found asynchronously by | ||
| 233 | * the receive interrupt routine. | ||
| 234 | */ | ||
| 235 | void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp) | ||
| 236 | { | ||
| 237 | struct ipath_qp *q, **qpp; | ||
| 238 | unsigned long flags; | ||
| 239 | int fnd = 0; | ||
| 240 | |||
| 241 | spin_lock_irqsave(&qpt->lock, flags); | ||
| 242 | |||
| 243 | /* Remove QP from the hash table. */ | ||
| 244 | qpp = &qpt->table[qp->ibqp.qp_num % qpt->max]; | ||
| 245 | for (; (q = *qpp) != NULL; qpp = &q->next) { | ||
| 246 | if (q == qp) { | ||
| 247 | *qpp = qp->next; | ||
| 248 | qp->next = NULL; | ||
| 249 | atomic_dec(&qp->refcount); | ||
| 250 | fnd = 1; | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | spin_unlock_irqrestore(&qpt->lock, flags); | ||
| 256 | |||
| 257 | if (!fnd) | ||
| 258 | return; | ||
| 259 | |||
| 260 | /* If QPN is not reserved, mark QPN free in the bitmap. */ | ||
| 261 | if (qp->ibqp.qp_num > 1) | ||
| 262 | free_qpn(qpt, qp->ibqp.qp_num); | ||
| 263 | |||
| 264 | wait_event(qp->wait, !atomic_read(&qp->refcount)); | ||
| 265 | } | ||
| 266 | |||
| 267 | /** | ||
| 268 | * ipath_free_all_qps - remove all QPs from the table | ||
| 269 | * @qpt: the QP table to empty | ||
| 270 | */ | ||
| 271 | void ipath_free_all_qps(struct ipath_qp_table *qpt) | ||
| 272 | { | ||
| 273 | unsigned long flags; | ||
| 274 | struct ipath_qp *qp, *nqp; | ||
| 275 | u32 n; | ||
| 276 | |||
| 277 | for (n = 0; n < qpt->max; n++) { | ||
| 278 | spin_lock_irqsave(&qpt->lock, flags); | ||
| 279 | qp = qpt->table[n]; | ||
| 280 | qpt->table[n] = NULL; | ||
| 281 | spin_unlock_irqrestore(&qpt->lock, flags); | ||
| 282 | |||
| 283 | while (qp) { | ||
| 284 | nqp = qp->next; | ||
| 285 | if (qp->ibqp.qp_num > 1) | ||
| 286 | free_qpn(qpt, qp->ibqp.qp_num); | ||
| 287 | if (!atomic_dec_and_test(&qp->refcount) || | ||
| 288 | !ipath_destroy_qp(&qp->ibqp)) | ||
| 289 | _VERBS_INFO("QP memory leak!\n"); | ||
| 290 | qp = nqp; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | for (n = 0; n < ARRAY_SIZE(qpt->map); n++) { | ||
| 295 | if (qpt->map[n].page) | ||
| 296 | free_page((unsigned long)qpt->map[n].page); | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | /** | ||
| 301 | * ipath_lookup_qpn - return the QP with the given QPN | ||
| 302 | * @qpt: the QP table | ||
| 303 | * @qpn: the QP number to look up | ||
| 304 | * | ||
| 305 | * The caller is responsible for decrementing the QP reference count | ||
| 306 | * when done. | ||
| 307 | */ | ||
| 308 | struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn) | ||
| 309 | { | ||
| 310 | unsigned long flags; | ||
| 311 | struct ipath_qp *qp; | ||
| 312 | |||
| 313 | spin_lock_irqsave(&qpt->lock, flags); | ||
| 314 | |||
| 315 | for (qp = qpt->table[qpn % qpt->max]; qp; qp = qp->next) { | ||
| 316 | if (qp->ibqp.qp_num == qpn) { | ||
| 317 | atomic_inc(&qp->refcount); | ||
| 318 | break; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | spin_unlock_irqrestore(&qpt->lock, flags); | ||
| 323 | return qp; | ||
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * ipath_reset_qp - initialize the QP state to the reset state | ||
| 328 | * @qp: the QP to reset | ||
| 329 | */ | ||
| 330 | static void ipath_reset_qp(struct ipath_qp *qp) | ||
| 331 | { | ||
| 332 | qp->remote_qpn = 0; | ||
| 333 | qp->qkey = 0; | ||
| 334 | qp->qp_access_flags = 0; | ||
| 335 | qp->s_hdrwords = 0; | ||
| 336 | qp->s_psn = 0; | ||
| 337 | qp->r_psn = 0; | ||
| 338 | atomic_set(&qp->msn, 0); | ||
| 339 | if (qp->ibqp.qp_type == IB_QPT_RC) { | ||
| 340 | qp->s_state = IB_OPCODE_RC_SEND_LAST; | ||
| 341 | qp->r_state = IB_OPCODE_RC_SEND_LAST; | ||
| 342 | } else { | ||
| 343 | qp->s_state = IB_OPCODE_UC_SEND_LAST; | ||
| 344 | qp->r_state = IB_OPCODE_UC_SEND_LAST; | ||
| 345 | } | ||
| 346 | qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; | ||
| 347 | qp->s_nak_state = 0; | ||
| 348 | qp->s_rnr_timeout = 0; | ||
| 349 | qp->s_head = 0; | ||
| 350 | qp->s_tail = 0; | ||
| 351 | qp->s_cur = 0; | ||
| 352 | qp->s_last = 0; | ||
| 353 | qp->s_ssn = 1; | ||
| 354 | qp->s_lsn = 0; | ||
| 355 | qp->r_rq.head = 0; | ||
| 356 | qp->r_rq.tail = 0; | ||
| 357 | qp->r_reuse_sge = 0; | ||
| 358 | } | ||
| 359 | |||
| 360 | /** | ||
| 361 | * ipath_modify_qp - modify the attributes of a queue pair | ||
| 362 | * @ibqp: the queue pair who's attributes we're modifying | ||
| 363 | * @attr: the new attributes | ||
| 364 | * @attr_mask: the mask of attributes to modify | ||
| 365 | * | ||
| 366 | * Returns 0 on success, otherwise returns an errno. | ||
| 367 | */ | ||
| 368 | int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 369 | int attr_mask) | ||
| 370 | { | ||
| 371 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 372 | enum ib_qp_state cur_state, new_state; | ||
| 373 | unsigned long flags; | ||
| 374 | int ret; | ||
| 375 | |||
| 376 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 377 | spin_lock(&qp->s_lock); | ||
| 378 | |||
| 379 | cur_state = attr_mask & IB_QP_CUR_STATE ? | ||
| 380 | attr->cur_qp_state : qp->state; | ||
| 381 | new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; | ||
| 382 | |||
| 383 | if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, | ||
| 384 | attr_mask)) | ||
| 385 | goto inval; | ||
| 386 | |||
| 387 | switch (new_state) { | ||
| 388 | case IB_QPS_RESET: | ||
| 389 | ipath_reset_qp(qp); | ||
| 390 | break; | ||
| 391 | |||
| 392 | case IB_QPS_ERR: | ||
| 393 | ipath_error_qp(qp); | ||
| 394 | break; | ||
| 395 | |||
| 396 | default: | ||
| 397 | break; | ||
| 398 | |||
| 399 | } | ||
| 400 | |||
| 401 | if (attr_mask & IB_QP_PKEY_INDEX) { | ||
| 402 | struct ipath_ibdev *dev = to_idev(ibqp->device); | ||
| 403 | |||
| 404 | if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd)) | ||
| 405 | goto inval; | ||
| 406 | qp->s_pkey_index = attr->pkey_index; | ||
| 407 | } | ||
| 408 | |||
| 409 | if (attr_mask & IB_QP_DEST_QPN) | ||
| 410 | qp->remote_qpn = attr->dest_qp_num; | ||
| 411 | |||
| 412 | if (attr_mask & IB_QP_SQ_PSN) { | ||
| 413 | qp->s_next_psn = attr->sq_psn; | ||
| 414 | qp->s_last_psn = qp->s_next_psn - 1; | ||
| 415 | } | ||
| 416 | |||
| 417 | if (attr_mask & IB_QP_RQ_PSN) | ||
| 418 | qp->r_psn = attr->rq_psn; | ||
| 419 | |||
| 420 | if (attr_mask & IB_QP_ACCESS_FLAGS) | ||
| 421 | qp->qp_access_flags = attr->qp_access_flags; | ||
| 422 | |||
| 423 | if (attr_mask & IB_QP_AV) { | ||
| 424 | if (attr->ah_attr.dlid == 0 || | ||
| 425 | attr->ah_attr.dlid >= IPS_MULTICAST_LID_BASE) | ||
| 426 | goto inval; | ||
| 427 | qp->remote_ah_attr = attr->ah_attr; | ||
| 428 | } | ||
| 429 | |||
| 430 | if (attr_mask & IB_QP_PATH_MTU) | ||
| 431 | qp->path_mtu = attr->path_mtu; | ||
| 432 | |||
| 433 | if (attr_mask & IB_QP_RETRY_CNT) | ||
| 434 | qp->s_retry = qp->s_retry_cnt = attr->retry_cnt; | ||
| 435 | |||
| 436 | if (attr_mask & IB_QP_RNR_RETRY) { | ||
| 437 | qp->s_rnr_retry = attr->rnr_retry; | ||
| 438 | if (qp->s_rnr_retry > 7) | ||
| 439 | qp->s_rnr_retry = 7; | ||
| 440 | qp->s_rnr_retry_cnt = qp->s_rnr_retry; | ||
| 441 | } | ||
| 442 | |||
| 443 | if (attr_mask & IB_QP_MIN_RNR_TIMER) { | ||
| 444 | if (attr->min_rnr_timer > 31) | ||
| 445 | goto inval; | ||
| 446 | qp->s_min_rnr_timer = attr->min_rnr_timer; | ||
| 447 | } | ||
| 448 | |||
| 449 | if (attr_mask & IB_QP_QKEY) | ||
| 450 | qp->qkey = attr->qkey; | ||
| 451 | |||
| 452 | if (attr_mask & IB_QP_PKEY_INDEX) | ||
| 453 | qp->s_pkey_index = attr->pkey_index; | ||
| 454 | |||
| 455 | qp->state = new_state; | ||
| 456 | spin_unlock(&qp->s_lock); | ||
| 457 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 458 | |||
| 459 | /* | ||
| 460 | * If QP1 changed to the RTS state, try to move to the link to INIT | ||
| 461 | * even if it was ACTIVE so the SM will reinitialize the SMA's | ||
| 462 | * state. | ||
| 463 | */ | ||
| 464 | if (qp->ibqp.qp_num == 1 && new_state == IB_QPS_RTS) { | ||
| 465 | struct ipath_ibdev *dev = to_idev(ibqp->device); | ||
| 466 | |||
| 467 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKDOWN); | ||
| 468 | } | ||
| 469 | ret = 0; | ||
| 470 | goto bail; | ||
| 471 | |||
| 472 | inval: | ||
| 473 | spin_unlock(&qp->s_lock); | ||
| 474 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 475 | ret = -EINVAL; | ||
| 476 | |||
| 477 | bail: | ||
| 478 | return ret; | ||
| 479 | } | ||
| 480 | |||
| 481 | int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 482 | int attr_mask, struct ib_qp_init_attr *init_attr) | ||
| 483 | { | ||
| 484 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 485 | |||
| 486 | attr->qp_state = qp->state; | ||
| 487 | attr->cur_qp_state = attr->qp_state; | ||
| 488 | attr->path_mtu = qp->path_mtu; | ||
| 489 | attr->path_mig_state = 0; | ||
| 490 | attr->qkey = qp->qkey; | ||
| 491 | attr->rq_psn = qp->r_psn; | ||
| 492 | attr->sq_psn = qp->s_next_psn; | ||
| 493 | attr->dest_qp_num = qp->remote_qpn; | ||
| 494 | attr->qp_access_flags = qp->qp_access_flags; | ||
| 495 | attr->cap.max_send_wr = qp->s_size - 1; | ||
| 496 | attr->cap.max_recv_wr = qp->r_rq.size - 1; | ||
| 497 | attr->cap.max_send_sge = qp->s_max_sge; | ||
| 498 | attr->cap.max_recv_sge = qp->r_rq.max_sge; | ||
| 499 | attr->cap.max_inline_data = 0; | ||
| 500 | attr->ah_attr = qp->remote_ah_attr; | ||
| 501 | memset(&attr->alt_ah_attr, 0, sizeof(attr->alt_ah_attr)); | ||
| 502 | attr->pkey_index = qp->s_pkey_index; | ||
| 503 | attr->alt_pkey_index = 0; | ||
| 504 | attr->en_sqd_async_notify = 0; | ||
| 505 | attr->sq_draining = 0; | ||
| 506 | attr->max_rd_atomic = 1; | ||
| 507 | attr->max_dest_rd_atomic = 1; | ||
| 508 | attr->min_rnr_timer = qp->s_min_rnr_timer; | ||
| 509 | attr->port_num = 1; | ||
| 510 | attr->timeout = 0; | ||
| 511 | attr->retry_cnt = qp->s_retry_cnt; | ||
| 512 | attr->rnr_retry = qp->s_rnr_retry; | ||
| 513 | attr->alt_port_num = 0; | ||
| 514 | attr->alt_timeout = 0; | ||
| 515 | |||
| 516 | init_attr->event_handler = qp->ibqp.event_handler; | ||
| 517 | init_attr->qp_context = qp->ibqp.qp_context; | ||
| 518 | init_attr->send_cq = qp->ibqp.send_cq; | ||
| 519 | init_attr->recv_cq = qp->ibqp.recv_cq; | ||
| 520 | init_attr->srq = qp->ibqp.srq; | ||
| 521 | init_attr->cap = attr->cap; | ||
| 522 | init_attr->sq_sig_type = | ||
| 523 | (qp->s_flags & (1 << IPATH_S_SIGNAL_REQ_WR)) | ||
| 524 | ? IB_SIGNAL_REQ_WR : 0; | ||
| 525 | init_attr->qp_type = qp->ibqp.qp_type; | ||
| 526 | init_attr->port_num = 1; | ||
| 527 | return 0; | ||
| 528 | } | ||
| 529 | |||
| 530 | /** | ||
| 531 | * ipath_compute_aeth - compute the AETH (syndrome + MSN) | ||
| 532 | * @qp: the queue pair to compute the AETH for | ||
| 533 | * | ||
| 534 | * Returns the AETH. | ||
| 535 | * | ||
| 536 | * The QP s_lock should be held. | ||
| 537 | */ | ||
| 538 | __be32 ipath_compute_aeth(struct ipath_qp *qp) | ||
| 539 | { | ||
| 540 | u32 aeth = atomic_read(&qp->msn) & IPS_MSN_MASK; | ||
| 541 | |||
| 542 | if (qp->s_nak_state) { | ||
| 543 | aeth |= qp->s_nak_state << IPS_AETH_CREDIT_SHIFT; | ||
| 544 | } else if (qp->ibqp.srq) { | ||
| 545 | /* | ||
| 546 | * Shared receive queues don't generate credits. | ||
| 547 | * Set the credit field to the invalid value. | ||
| 548 | */ | ||
| 549 | aeth |= IPS_AETH_CREDIT_INVAL << IPS_AETH_CREDIT_SHIFT; | ||
| 550 | } else { | ||
| 551 | u32 min, max, x; | ||
| 552 | u32 credits; | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Compute the number of credits available (RWQEs). | ||
| 556 | * XXX Not holding the r_rq.lock here so there is a small | ||
| 557 | * chance that the pair of reads are not atomic. | ||
| 558 | */ | ||
| 559 | credits = qp->r_rq.head - qp->r_rq.tail; | ||
| 560 | if ((int)credits < 0) | ||
| 561 | credits += qp->r_rq.size; | ||
| 562 | /* | ||
| 563 | * Binary search the credit table to find the code to | ||
| 564 | * use. | ||
| 565 | */ | ||
| 566 | min = 0; | ||
| 567 | max = 31; | ||
| 568 | for (;;) { | ||
| 569 | x = (min + max) / 2; | ||
| 570 | if (credit_table[x] == credits) | ||
| 571 | break; | ||
| 572 | if (credit_table[x] > credits) | ||
| 573 | max = x; | ||
| 574 | else if (min == x) | ||
| 575 | break; | ||
| 576 | else | ||
| 577 | min = x; | ||
| 578 | } | ||
| 579 | aeth |= x << IPS_AETH_CREDIT_SHIFT; | ||
| 580 | } | ||
| 581 | return cpu_to_be32(aeth); | ||
| 582 | } | ||
| 583 | |||
| 584 | /** | ||
| 585 | * ipath_create_qp - create a queue pair for a device | ||
| 586 | * @ibpd: the protection domain who's device we create the queue pair for | ||
| 587 | * @init_attr: the attributes of the queue pair | ||
| 588 | * @udata: unused by InfiniPath | ||
| 589 | * | ||
| 590 | * Returns the queue pair on success, otherwise returns an errno. | ||
| 591 | * | ||
| 592 | * Called by the ib_create_qp() core verbs function. | ||
| 593 | */ | ||
| 594 | struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | ||
| 595 | struct ib_qp_init_attr *init_attr, | ||
| 596 | struct ib_udata *udata) | ||
| 597 | { | ||
| 598 | struct ipath_qp *qp; | ||
| 599 | int err; | ||
| 600 | struct ipath_swqe *swq = NULL; | ||
| 601 | struct ipath_ibdev *dev; | ||
| 602 | size_t sz; | ||
| 603 | struct ib_qp *ret; | ||
| 604 | |||
| 605 | if (init_attr->cap.max_send_sge > 255 || | ||
| 606 | init_attr->cap.max_recv_sge > 255) { | ||
| 607 | ret = ERR_PTR(-ENOMEM); | ||
| 608 | goto bail; | ||
| 609 | } | ||
| 610 | |||
| 611 | switch (init_attr->qp_type) { | ||
| 612 | case IB_QPT_UC: | ||
| 613 | case IB_QPT_RC: | ||
| 614 | sz = sizeof(struct ipath_sge) * | ||
| 615 | init_attr->cap.max_send_sge + | ||
| 616 | sizeof(struct ipath_swqe); | ||
| 617 | swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz); | ||
| 618 | if (swq == NULL) { | ||
| 619 | ret = ERR_PTR(-ENOMEM); | ||
| 620 | goto bail; | ||
| 621 | } | ||
| 622 | /* FALLTHROUGH */ | ||
| 623 | case IB_QPT_UD: | ||
| 624 | case IB_QPT_SMI: | ||
| 625 | case IB_QPT_GSI: | ||
| 626 | qp = kmalloc(sizeof(*qp), GFP_KERNEL); | ||
| 627 | if (!qp) { | ||
| 628 | ret = ERR_PTR(-ENOMEM); | ||
| 629 | goto bail; | ||
| 630 | } | ||
| 631 | qp->r_rq.size = init_attr->cap.max_recv_wr + 1; | ||
| 632 | sz = sizeof(struct ipath_sge) * | ||
| 633 | init_attr->cap.max_recv_sge + | ||
| 634 | sizeof(struct ipath_rwqe); | ||
| 635 | qp->r_rq.wq = vmalloc(qp->r_rq.size * sz); | ||
| 636 | if (!qp->r_rq.wq) { | ||
| 637 | kfree(qp); | ||
| 638 | ret = ERR_PTR(-ENOMEM); | ||
| 639 | goto bail; | ||
| 640 | } | ||
| 641 | |||
| 642 | /* | ||
| 643 | * ib_create_qp() will initialize qp->ibqp | ||
| 644 | * except for qp->ibqp.qp_num. | ||
| 645 | */ | ||
| 646 | spin_lock_init(&qp->s_lock); | ||
| 647 | spin_lock_init(&qp->r_rq.lock); | ||
| 648 | atomic_set(&qp->refcount, 0); | ||
| 649 | init_waitqueue_head(&qp->wait); | ||
| 650 | tasklet_init(&qp->s_task, | ||
| 651 | init_attr->qp_type == IB_QPT_RC ? | ||
| 652 | ipath_do_rc_send : ipath_do_uc_send, | ||
| 653 | (unsigned long)qp); | ||
| 654 | qp->piowait.next = LIST_POISON1; | ||
| 655 | qp->piowait.prev = LIST_POISON2; | ||
| 656 | qp->timerwait.next = LIST_POISON1; | ||
| 657 | qp->timerwait.prev = LIST_POISON2; | ||
| 658 | qp->state = IB_QPS_RESET; | ||
| 659 | qp->s_wq = swq; | ||
| 660 | qp->s_size = init_attr->cap.max_send_wr + 1; | ||
| 661 | qp->s_max_sge = init_attr->cap.max_send_sge; | ||
| 662 | qp->r_rq.max_sge = init_attr->cap.max_recv_sge; | ||
| 663 | qp->s_flags = init_attr->sq_sig_type == IB_SIGNAL_REQ_WR ? | ||
| 664 | 1 << IPATH_S_SIGNAL_REQ_WR : 0; | ||
| 665 | dev = to_idev(ibpd->device); | ||
| 666 | err = ipath_alloc_qpn(&dev->qp_table, qp, | ||
| 667 | init_attr->qp_type); | ||
| 668 | if (err) { | ||
| 669 | vfree(swq); | ||
| 670 | vfree(qp->r_rq.wq); | ||
| 671 | kfree(qp); | ||
| 672 | ret = ERR_PTR(err); | ||
| 673 | goto bail; | ||
| 674 | } | ||
| 675 | ipath_reset_qp(qp); | ||
| 676 | |||
| 677 | /* Tell the core driver that the kernel SMA is present. */ | ||
| 678 | if (qp->ibqp.qp_type == IB_QPT_SMI) | ||
| 679 | ipath_layer_set_verbs_flags(dev->dd, | ||
| 680 | IPATH_VERBS_KERNEL_SMA); | ||
| 681 | break; | ||
| 682 | |||
| 683 | default: | ||
| 684 | /* Don't support raw QPs */ | ||
| 685 | ret = ERR_PTR(-ENOSYS); | ||
| 686 | goto bail; | ||
| 687 | } | ||
| 688 | |||
| 689 | init_attr->cap.max_inline_data = 0; | ||
| 690 | |||
| 691 | ret = &qp->ibqp; | ||
| 692 | |||
| 693 | bail: | ||
| 694 | return ret; | ||
| 695 | } | ||
| 696 | |||
| 697 | /** | ||
| 698 | * ipath_destroy_qp - destroy a queue pair | ||
| 699 | * @ibqp: the queue pair to destroy | ||
| 700 | * | ||
| 701 | * Returns 0 on success. | ||
| 702 | * | ||
| 703 | * Note that this can be called while the QP is actively sending or | ||
| 704 | * receiving! | ||
| 705 | */ | ||
| 706 | int ipath_destroy_qp(struct ib_qp *ibqp) | ||
| 707 | { | ||
| 708 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 709 | struct ipath_ibdev *dev = to_idev(ibqp->device); | ||
| 710 | unsigned long flags; | ||
| 711 | |||
| 712 | /* Tell the core driver that the kernel SMA is gone. */ | ||
| 713 | if (qp->ibqp.qp_type == IB_QPT_SMI) | ||
| 714 | ipath_layer_set_verbs_flags(dev->dd, 0); | ||
| 715 | |||
| 716 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 717 | spin_lock(&qp->s_lock); | ||
| 718 | qp->state = IB_QPS_ERR; | ||
| 719 | spin_unlock(&qp->s_lock); | ||
| 720 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 721 | |||
| 722 | /* Stop the sending tasklet. */ | ||
| 723 | tasklet_kill(&qp->s_task); | ||
| 724 | |||
| 725 | /* Make sure the QP isn't on the timeout list. */ | ||
| 726 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 727 | if (qp->timerwait.next != LIST_POISON1) | ||
| 728 | list_del(&qp->timerwait); | ||
| 729 | if (qp->piowait.next != LIST_POISON1) | ||
| 730 | list_del(&qp->piowait); | ||
| 731 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 732 | |||
| 733 | /* | ||
| 734 | * Make sure that the QP is not in the QPN table so receive | ||
| 735 | * interrupts will discard packets for this QP. XXX Also remove QP | ||
| 736 | * from multicast table. | ||
| 737 | */ | ||
| 738 | if (atomic_read(&qp->refcount) != 0) | ||
| 739 | ipath_free_qp(&dev->qp_table, qp); | ||
| 740 | |||
| 741 | vfree(qp->s_wq); | ||
| 742 | vfree(qp->r_rq.wq); | ||
| 743 | kfree(qp); | ||
| 744 | return 0; | ||
| 745 | } | ||
| 746 | |||
| 747 | /** | ||
| 748 | * ipath_init_qp_table - initialize the QP table for a device | ||
| 749 | * @idev: the device who's QP table we're initializing | ||
| 750 | * @size: the size of the QP table | ||
| 751 | * | ||
| 752 | * Returns 0 on success, otherwise returns an errno. | ||
| 753 | */ | ||
| 754 | int ipath_init_qp_table(struct ipath_ibdev *idev, int size) | ||
| 755 | { | ||
| 756 | int i; | ||
| 757 | int ret; | ||
| 758 | |||
| 759 | idev->qp_table.last = 1; /* QPN 0 and 1 are special. */ | ||
| 760 | idev->qp_table.max = size; | ||
| 761 | idev->qp_table.nmaps = 1; | ||
| 762 | idev->qp_table.table = kzalloc(size * sizeof(*idev->qp_table.table), | ||
| 763 | GFP_KERNEL); | ||
| 764 | if (idev->qp_table.table == NULL) { | ||
| 765 | ret = -ENOMEM; | ||
| 766 | goto bail; | ||
| 767 | } | ||
| 768 | |||
| 769 | for (i = 0; i < ARRAY_SIZE(idev->qp_table.map); i++) { | ||
| 770 | atomic_set(&idev->qp_table.map[i].n_free, BITS_PER_PAGE); | ||
| 771 | idev->qp_table.map[i].page = NULL; | ||
| 772 | } | ||
| 773 | |||
| 774 | ret = 0; | ||
| 775 | |||
| 776 | bail: | ||
| 777 | return ret; | ||
| 778 | } | ||
| 779 | |||
| 780 | /** | ||
| 781 | * ipath_sqerror_qp - put a QP's send queue into an error state | ||
| 782 | * @qp: QP who's send queue will be put into an error state | ||
| 783 | * @wc: the WC responsible for putting the QP in this state | ||
| 784 | * | ||
| 785 | * Flushes the send work queue. | ||
| 786 | * The QP s_lock should be held. | ||
| 787 | */ | ||
| 788 | |||
| 789 | void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc) | ||
| 790 | { | ||
| 791 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 792 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 793 | |||
| 794 | _VERBS_INFO("Send queue error on QP%d/%d: err: %d\n", | ||
| 795 | qp->ibqp.qp_num, qp->remote_qpn, wc->status); | ||
| 796 | |||
| 797 | spin_lock(&dev->pending_lock); | ||
| 798 | /* XXX What if its already removed by the timeout code? */ | ||
| 799 | if (qp->timerwait.next != LIST_POISON1) | ||
| 800 | list_del(&qp->timerwait); | ||
| 801 | if (qp->piowait.next != LIST_POISON1) | ||
| 802 | list_del(&qp->piowait); | ||
| 803 | spin_unlock(&dev->pending_lock); | ||
| 804 | |||
| 805 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1); | ||
| 806 | if (++qp->s_last >= qp->s_size) | ||
| 807 | qp->s_last = 0; | ||
| 808 | |||
| 809 | wc->status = IB_WC_WR_FLUSH_ERR; | ||
| 810 | |||
| 811 | while (qp->s_last != qp->s_head) { | ||
| 812 | wc->wr_id = wqe->wr.wr_id; | ||
| 813 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 814 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1); | ||
| 815 | if (++qp->s_last >= qp->s_size) | ||
| 816 | qp->s_last = 0; | ||
| 817 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 818 | } | ||
| 819 | qp->s_cur = qp->s_tail = qp->s_head; | ||
| 820 | qp->state = IB_QPS_SQE; | ||
| 821 | } | ||
| 822 | |||
| 823 | /** | ||
| 824 | * ipath_error_qp - put a QP into an error state | ||
| 825 | * @qp: the QP to put into an error state | ||
| 826 | * | ||
| 827 | * Flushes both send and receive work queues. | ||
| 828 | * QP r_rq.lock and s_lock should be held. | ||
| 829 | */ | ||
| 830 | |||
| 831 | void ipath_error_qp(struct ipath_qp *qp) | ||
| 832 | { | ||
| 833 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 834 | struct ib_wc wc; | ||
| 835 | |||
| 836 | _VERBS_INFO("QP%d/%d in error state\n", | ||
| 837 | qp->ibqp.qp_num, qp->remote_qpn); | ||
| 838 | |||
| 839 | spin_lock(&dev->pending_lock); | ||
| 840 | /* XXX What if its already removed by the timeout code? */ | ||
| 841 | if (qp->timerwait.next != LIST_POISON1) | ||
| 842 | list_del(&qp->timerwait); | ||
| 843 | if (qp->piowait.next != LIST_POISON1) | ||
| 844 | list_del(&qp->piowait); | ||
| 845 | spin_unlock(&dev->pending_lock); | ||
| 846 | |||
| 847 | wc.status = IB_WC_WR_FLUSH_ERR; | ||
| 848 | wc.vendor_err = 0; | ||
| 849 | wc.byte_len = 0; | ||
| 850 | wc.imm_data = 0; | ||
| 851 | wc.qp_num = qp->ibqp.qp_num; | ||
| 852 | wc.src_qp = 0; | ||
| 853 | wc.wc_flags = 0; | ||
| 854 | wc.pkey_index = 0; | ||
| 855 | wc.slid = 0; | ||
| 856 | wc.sl = 0; | ||
| 857 | wc.dlid_path_bits = 0; | ||
| 858 | wc.port_num = 0; | ||
| 859 | |||
| 860 | while (qp->s_last != qp->s_head) { | ||
| 861 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 862 | |||
| 863 | wc.wr_id = wqe->wr.wr_id; | ||
| 864 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 865 | if (++qp->s_last >= qp->s_size) | ||
| 866 | qp->s_last = 0; | ||
| 867 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); | ||
| 868 | } | ||
| 869 | qp->s_cur = qp->s_tail = qp->s_head; | ||
| 870 | qp->s_hdrwords = 0; | ||
| 871 | qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; | ||
| 872 | |||
| 873 | wc.opcode = IB_WC_RECV; | ||
| 874 | while (qp->r_rq.tail != qp->r_rq.head) { | ||
| 875 | wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id; | ||
| 876 | if (++qp->r_rq.tail >= qp->r_rq.size) | ||
| 877 | qp->r_rq.tail = 0; | ||
| 878 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | ||
| 879 | } | ||
| 880 | } | ||
| 881 | |||
| 882 | /** | ||
| 883 | * ipath_get_credit - flush the send work queue of a QP | ||
| 884 | * @qp: the qp who's send work queue to flush | ||
| 885 | * @aeth: the Acknowledge Extended Transport Header | ||
| 886 | * | ||
| 887 | * The QP s_lock should be held. | ||
| 888 | */ | ||
| 889 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth) | ||
| 890 | { | ||
| 891 | u32 credit = (aeth >> IPS_AETH_CREDIT_SHIFT) & IPS_AETH_CREDIT_MASK; | ||
| 892 | |||
| 893 | /* | ||
| 894 | * If the credit is invalid, we can send | ||
| 895 | * as many packets as we like. Otherwise, we have to | ||
| 896 | * honor the credit field. | ||
| 897 | */ | ||
| 898 | if (credit == IPS_AETH_CREDIT_INVAL) { | ||
| 899 | qp->s_lsn = (u32) -1; | ||
| 900 | } else if (qp->s_lsn != (u32) -1) { | ||
| 901 | /* Compute new LSN (i.e., MSN + credit) */ | ||
| 902 | credit = (aeth + credit_table[credit]) & IPS_MSN_MASK; | ||
| 903 | if (ipath_cmp24(credit, qp->s_lsn) > 0) | ||
| 904 | qp->s_lsn = credit; | ||
| 905 | } | ||
| 906 | |||
| 907 | /* Restart sending if it was blocked due to lack of credits. */ | ||
| 908 | if (qp->s_cur != qp->s_head && | ||
| 909 | (qp->s_lsn == (u32) -1 || | ||
| 910 | ipath_cmp24(get_swqe_ptr(qp, qp->s_cur)->ssn, | ||
| 911 | qp->s_lsn + 1) <= 0)) | ||
| 912 | tasklet_hi_schedule(&qp->s_task); | ||
| 913 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c new file mode 100644 index 000000000000..a4055ca00614 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
| @@ -0,0 +1,1857 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "ipath_verbs.h" | ||
| 34 | #include "ips_common.h" | ||
| 35 | |||
| 36 | /* cut down ridiculously long IB macro names */ | ||
| 37 | #define OP(x) IB_OPCODE_RC_##x | ||
| 38 | |||
| 39 | /** | ||
| 40 | * ipath_init_restart- initialize the qp->s_sge after a restart | ||
| 41 | * @qp: the QP who's SGE we're restarting | ||
| 42 | * @wqe: the work queue to initialize the QP's SGE from | ||
| 43 | * | ||
| 44 | * The QP s_lock should be held. | ||
| 45 | */ | ||
| 46 | static void ipath_init_restart(struct ipath_qp *qp, struct ipath_swqe *wqe) | ||
| 47 | { | ||
| 48 | struct ipath_ibdev *dev; | ||
| 49 | u32 len; | ||
| 50 | |||
| 51 | len = ((qp->s_psn - wqe->psn) & IPS_PSN_MASK) * | ||
| 52 | ib_mtu_enum_to_int(qp->path_mtu); | ||
| 53 | qp->s_sge.sge = wqe->sg_list[0]; | ||
| 54 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
| 55 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
| 56 | ipath_skip_sge(&qp->s_sge, len); | ||
| 57 | qp->s_len = wqe->length - len; | ||
| 58 | dev = to_idev(qp->ibqp.device); | ||
| 59 | spin_lock(&dev->pending_lock); | ||
| 60 | if (qp->timerwait.next == LIST_POISON1) | ||
| 61 | list_add_tail(&qp->timerwait, | ||
| 62 | &dev->pending[dev->pending_index]); | ||
| 63 | spin_unlock(&dev->pending_lock); | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * ipath_make_rc_ack - construct a response packet (ACK, NAK, or RDMA read) | ||
| 68 | * @qp: a pointer to the QP | ||
| 69 | * @ohdr: a pointer to the IB header being constructed | ||
| 70 | * @pmtu: the path MTU | ||
| 71 | * | ||
| 72 | * Return bth0 if constructed; otherwise, return 0. | ||
| 73 | * Note the QP s_lock must be held. | ||
| 74 | */ | ||
| 75 | static inline u32 ipath_make_rc_ack(struct ipath_qp *qp, | ||
| 76 | struct ipath_other_headers *ohdr, | ||
| 77 | u32 pmtu) | ||
| 78 | { | ||
| 79 | struct ipath_sge_state *ss; | ||
| 80 | u32 hwords; | ||
| 81 | u32 len; | ||
| 82 | u32 bth0; | ||
| 83 | |||
| 84 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ | ||
| 85 | hwords = 5; | ||
| 86 | |||
| 87 | /* | ||
| 88 | * Send a response. Note that we are in the responder's | ||
| 89 | * side of the QP context. | ||
| 90 | */ | ||
| 91 | switch (qp->s_ack_state) { | ||
| 92 | case OP(RDMA_READ_REQUEST): | ||
| 93 | ss = &qp->s_rdma_sge; | ||
| 94 | len = qp->s_rdma_len; | ||
| 95 | if (len > pmtu) { | ||
| 96 | len = pmtu; | ||
| 97 | qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
| 98 | } | ||
| 99 | else | ||
| 100 | qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY); | ||
| 101 | qp->s_rdma_len -= len; | ||
| 102 | bth0 = qp->s_ack_state << 24; | ||
| 103 | ohdr->u.aeth = ipath_compute_aeth(qp); | ||
| 104 | hwords++; | ||
| 105 | break; | ||
| 106 | |||
| 107 | case OP(RDMA_READ_RESPONSE_FIRST): | ||
| 108 | qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE); | ||
| 109 | /* FALLTHROUGH */ | ||
| 110 | case OP(RDMA_READ_RESPONSE_MIDDLE): | ||
| 111 | ss = &qp->s_rdma_sge; | ||
| 112 | len = qp->s_rdma_len; | ||
| 113 | if (len > pmtu) | ||
| 114 | len = pmtu; | ||
| 115 | else { | ||
| 116 | ohdr->u.aeth = ipath_compute_aeth(qp); | ||
| 117 | hwords++; | ||
| 118 | qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST); | ||
| 119 | } | ||
| 120 | qp->s_rdma_len -= len; | ||
| 121 | bth0 = qp->s_ack_state << 24; | ||
| 122 | break; | ||
| 123 | |||
| 124 | case OP(RDMA_READ_RESPONSE_LAST): | ||
| 125 | case OP(RDMA_READ_RESPONSE_ONLY): | ||
| 126 | /* | ||
| 127 | * We have to prevent new requests from changing | ||
| 128 | * the r_sge state while a ipath_verbs_send() | ||
| 129 | * is in progress. | ||
| 130 | * Changing r_state allows the receiver | ||
| 131 | * to continue processing new packets. | ||
| 132 | * We do it here now instead of above so | ||
| 133 | * that we are sure the packet was sent before | ||
| 134 | * changing the state. | ||
| 135 | */ | ||
| 136 | qp->r_state = OP(RDMA_READ_RESPONSE_LAST); | ||
| 137 | qp->s_ack_state = OP(ACKNOWLEDGE); | ||
| 138 | return 0; | ||
| 139 | |||
| 140 | case OP(COMPARE_SWAP): | ||
| 141 | case OP(FETCH_ADD): | ||
| 142 | ss = NULL; | ||
| 143 | len = 0; | ||
| 144 | qp->r_state = OP(SEND_LAST); | ||
| 145 | qp->s_ack_state = OP(ACKNOWLEDGE); | ||
| 146 | bth0 = IB_OPCODE_ATOMIC_ACKNOWLEDGE << 24; | ||
| 147 | ohdr->u.at.aeth = ipath_compute_aeth(qp); | ||
| 148 | ohdr->u.at.atomic_ack_eth = cpu_to_be64(qp->s_ack_atomic); | ||
| 149 | hwords += sizeof(ohdr->u.at) / 4; | ||
| 150 | break; | ||
| 151 | |||
| 152 | default: | ||
| 153 | /* Send a regular ACK. */ | ||
| 154 | ss = NULL; | ||
| 155 | len = 0; | ||
| 156 | qp->s_ack_state = OP(ACKNOWLEDGE); | ||
| 157 | bth0 = qp->s_ack_state << 24; | ||
| 158 | ohdr->u.aeth = ipath_compute_aeth(qp); | ||
| 159 | hwords++; | ||
| 160 | } | ||
| 161 | qp->s_hdrwords = hwords; | ||
| 162 | qp->s_cur_sge = ss; | ||
| 163 | qp->s_cur_size = len; | ||
| 164 | |||
| 165 | return bth0; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * ipath_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) | ||
| 170 | * @qp: a pointer to the QP | ||
| 171 | * @ohdr: a pointer to the IB header being constructed | ||
| 172 | * @pmtu: the path MTU | ||
| 173 | * @bth0p: pointer to the BTH opcode word | ||
| 174 | * @bth2p: pointer to the BTH PSN word | ||
| 175 | * | ||
| 176 | * Return 1 if constructed; otherwise, return 0. | ||
| 177 | * Note the QP s_lock must be held. | ||
| 178 | */ | ||
| 179 | static inline int ipath_make_rc_req(struct ipath_qp *qp, | ||
| 180 | struct ipath_other_headers *ohdr, | ||
| 181 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
| 182 | { | ||
| 183 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 184 | struct ipath_sge_state *ss; | ||
| 185 | struct ipath_swqe *wqe; | ||
| 186 | u32 hwords; | ||
| 187 | u32 len; | ||
| 188 | u32 bth0; | ||
| 189 | u32 bth2; | ||
| 190 | char newreq; | ||
| 191 | |||
| 192 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || | ||
| 193 | qp->s_rnr_timeout) | ||
| 194 | goto done; | ||
| 195 | |||
| 196 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ | ||
| 197 | hwords = 5; | ||
| 198 | bth0 = 0; | ||
| 199 | |||
| 200 | /* Send a request. */ | ||
| 201 | wqe = get_swqe_ptr(qp, qp->s_cur); | ||
| 202 | switch (qp->s_state) { | ||
| 203 | default: | ||
| 204 | /* | ||
| 205 | * Resend an old request or start a new one. | ||
| 206 | * | ||
| 207 | * We keep track of the current SWQE so that | ||
| 208 | * we don't reset the "furthest progress" state | ||
| 209 | * if we need to back up. | ||
| 210 | */ | ||
| 211 | newreq = 0; | ||
| 212 | if (qp->s_cur == qp->s_tail) { | ||
| 213 | /* Check if send work queue is empty. */ | ||
| 214 | if (qp->s_tail == qp->s_head) | ||
| 215 | goto done; | ||
| 216 | qp->s_psn = wqe->psn = qp->s_next_psn; | ||
| 217 | newreq = 1; | ||
| 218 | } | ||
| 219 | /* | ||
| 220 | * Note that we have to be careful not to modify the | ||
| 221 | * original work request since we may need to resend | ||
| 222 | * it. | ||
| 223 | */ | ||
| 224 | qp->s_sge.sge = wqe->sg_list[0]; | ||
| 225 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
| 226 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
| 227 | qp->s_len = len = wqe->length; | ||
| 228 | ss = &qp->s_sge; | ||
| 229 | bth2 = 0; | ||
| 230 | switch (wqe->wr.opcode) { | ||
| 231 | case IB_WR_SEND: | ||
| 232 | case IB_WR_SEND_WITH_IMM: | ||
| 233 | /* If no credit, return. */ | ||
| 234 | if (qp->s_lsn != (u32) -1 && | ||
| 235 | ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) | ||
| 236 | goto done; | ||
| 237 | wqe->lpsn = wqe->psn; | ||
| 238 | if (len > pmtu) { | ||
| 239 | wqe->lpsn += (len - 1) / pmtu; | ||
| 240 | qp->s_state = OP(SEND_FIRST); | ||
| 241 | len = pmtu; | ||
| 242 | break; | ||
| 243 | } | ||
| 244 | if (wqe->wr.opcode == IB_WR_SEND) | ||
| 245 | qp->s_state = OP(SEND_ONLY); | ||
| 246 | else { | ||
| 247 | qp->s_state = OP(SEND_ONLY_WITH_IMMEDIATE); | ||
| 248 | /* Immediate data comes after the BTH */ | ||
| 249 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 250 | hwords += 1; | ||
| 251 | } | ||
| 252 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 253 | bth0 |= 1 << 23; | ||
| 254 | bth2 = 1 << 31; /* Request ACK. */ | ||
| 255 | if (++qp->s_cur == qp->s_size) | ||
| 256 | qp->s_cur = 0; | ||
| 257 | break; | ||
| 258 | |||
| 259 | case IB_WR_RDMA_WRITE: | ||
| 260 | if (newreq) | ||
| 261 | qp->s_lsn++; | ||
| 262 | /* FALLTHROUGH */ | ||
| 263 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
| 264 | /* If no credit, return. */ | ||
| 265 | if (qp->s_lsn != (u32) -1 && | ||
| 266 | ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) | ||
| 267 | goto done; | ||
| 268 | ohdr->u.rc.reth.vaddr = | ||
| 269 | cpu_to_be64(wqe->wr.wr.rdma.remote_addr); | ||
| 270 | ohdr->u.rc.reth.rkey = | ||
| 271 | cpu_to_be32(wqe->wr.wr.rdma.rkey); | ||
| 272 | ohdr->u.rc.reth.length = cpu_to_be32(len); | ||
| 273 | hwords += sizeof(struct ib_reth) / 4; | ||
| 274 | wqe->lpsn = wqe->psn; | ||
| 275 | if (len > pmtu) { | ||
| 276 | wqe->lpsn += (len - 1) / pmtu; | ||
| 277 | qp->s_state = OP(RDMA_WRITE_FIRST); | ||
| 278 | len = pmtu; | ||
| 279 | break; | ||
| 280 | } | ||
| 281 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE) | ||
| 282 | qp->s_state = OP(RDMA_WRITE_ONLY); | ||
| 283 | else { | ||
| 284 | qp->s_state = | ||
| 285 | OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); | ||
| 286 | /* Immediate data comes | ||
| 287 | * after RETH */ | ||
| 288 | ohdr->u.rc.imm_data = wqe->wr.imm_data; | ||
| 289 | hwords += 1; | ||
| 290 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 291 | bth0 |= 1 << 23; | ||
| 292 | } | ||
| 293 | bth2 = 1 << 31; /* Request ACK. */ | ||
| 294 | if (++qp->s_cur == qp->s_size) | ||
| 295 | qp->s_cur = 0; | ||
| 296 | break; | ||
| 297 | |||
| 298 | case IB_WR_RDMA_READ: | ||
| 299 | ohdr->u.rc.reth.vaddr = | ||
| 300 | cpu_to_be64(wqe->wr.wr.rdma.remote_addr); | ||
| 301 | ohdr->u.rc.reth.rkey = | ||
| 302 | cpu_to_be32(wqe->wr.wr.rdma.rkey); | ||
| 303 | ohdr->u.rc.reth.length = cpu_to_be32(len); | ||
| 304 | qp->s_state = OP(RDMA_READ_REQUEST); | ||
| 305 | hwords += sizeof(ohdr->u.rc.reth) / 4; | ||
| 306 | if (newreq) { | ||
| 307 | qp->s_lsn++; | ||
| 308 | /* | ||
| 309 | * Adjust s_next_psn to count the | ||
| 310 | * expected number of responses. | ||
| 311 | */ | ||
| 312 | if (len > pmtu) | ||
| 313 | qp->s_next_psn += (len - 1) / pmtu; | ||
| 314 | wqe->lpsn = qp->s_next_psn++; | ||
| 315 | } | ||
| 316 | ss = NULL; | ||
| 317 | len = 0; | ||
| 318 | if (++qp->s_cur == qp->s_size) | ||
| 319 | qp->s_cur = 0; | ||
| 320 | break; | ||
| 321 | |||
| 322 | case IB_WR_ATOMIC_CMP_AND_SWP: | ||
| 323 | case IB_WR_ATOMIC_FETCH_AND_ADD: | ||
| 324 | if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP) | ||
| 325 | qp->s_state = OP(COMPARE_SWAP); | ||
| 326 | else | ||
| 327 | qp->s_state = OP(FETCH_ADD); | ||
| 328 | ohdr->u.atomic_eth.vaddr = cpu_to_be64( | ||
| 329 | wqe->wr.wr.atomic.remote_addr); | ||
| 330 | ohdr->u.atomic_eth.rkey = cpu_to_be32( | ||
| 331 | wqe->wr.wr.atomic.rkey); | ||
| 332 | ohdr->u.atomic_eth.swap_data = cpu_to_be64( | ||
| 333 | wqe->wr.wr.atomic.swap); | ||
| 334 | ohdr->u.atomic_eth.compare_data = cpu_to_be64( | ||
| 335 | wqe->wr.wr.atomic.compare_add); | ||
| 336 | hwords += sizeof(struct ib_atomic_eth) / 4; | ||
| 337 | if (newreq) { | ||
| 338 | qp->s_lsn++; | ||
| 339 | wqe->lpsn = wqe->psn; | ||
| 340 | } | ||
| 341 | if (++qp->s_cur == qp->s_size) | ||
| 342 | qp->s_cur = 0; | ||
| 343 | ss = NULL; | ||
| 344 | len = 0; | ||
| 345 | break; | ||
| 346 | |||
| 347 | default: | ||
| 348 | goto done; | ||
| 349 | } | ||
| 350 | if (newreq) { | ||
| 351 | qp->s_tail++; | ||
| 352 | if (qp->s_tail >= qp->s_size) | ||
| 353 | qp->s_tail = 0; | ||
| 354 | } | ||
| 355 | bth2 |= qp->s_psn++ & IPS_PSN_MASK; | ||
| 356 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | ||
| 357 | qp->s_next_psn = qp->s_psn; | ||
| 358 | spin_lock(&dev->pending_lock); | ||
| 359 | if (qp->timerwait.next == LIST_POISON1) | ||
| 360 | list_add_tail(&qp->timerwait, | ||
| 361 | &dev->pending[dev->pending_index]); | ||
| 362 | spin_unlock(&dev->pending_lock); | ||
| 363 | break; | ||
| 364 | |||
| 365 | case OP(RDMA_READ_RESPONSE_FIRST): | ||
| 366 | /* | ||
| 367 | * This case can only happen if a send is restarted. See | ||
| 368 | * ipath_restart_rc(). | ||
| 369 | */ | ||
| 370 | ipath_init_restart(qp, wqe); | ||
| 371 | /* FALLTHROUGH */ | ||
| 372 | case OP(SEND_FIRST): | ||
| 373 | qp->s_state = OP(SEND_MIDDLE); | ||
| 374 | /* FALLTHROUGH */ | ||
| 375 | case OP(SEND_MIDDLE): | ||
| 376 | bth2 = qp->s_psn++ & IPS_PSN_MASK; | ||
| 377 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | ||
| 378 | qp->s_next_psn = qp->s_psn; | ||
| 379 | ss = &qp->s_sge; | ||
| 380 | len = qp->s_len; | ||
| 381 | if (len > pmtu) { | ||
| 382 | /* | ||
| 383 | * Request an ACK every 1/2 MB to avoid retransmit | ||
| 384 | * timeouts. | ||
| 385 | */ | ||
| 386 | if (((wqe->length - len) % (512 * 1024)) == 0) | ||
| 387 | bth2 |= 1 << 31; | ||
| 388 | len = pmtu; | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | if (wqe->wr.opcode == IB_WR_SEND) | ||
| 392 | qp->s_state = OP(SEND_LAST); | ||
| 393 | else { | ||
| 394 | qp->s_state = OP(SEND_LAST_WITH_IMMEDIATE); | ||
| 395 | /* Immediate data comes after the BTH */ | ||
| 396 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 397 | hwords += 1; | ||
| 398 | } | ||
| 399 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 400 | bth0 |= 1 << 23; | ||
| 401 | bth2 |= 1 << 31; /* Request ACK. */ | ||
| 402 | qp->s_cur++; | ||
| 403 | if (qp->s_cur >= qp->s_size) | ||
| 404 | qp->s_cur = 0; | ||
| 405 | break; | ||
| 406 | |||
| 407 | case OP(RDMA_READ_RESPONSE_LAST): | ||
| 408 | /* | ||
| 409 | * This case can only happen if a RDMA write is restarted. | ||
| 410 | * See ipath_restart_rc(). | ||
| 411 | */ | ||
| 412 | ipath_init_restart(qp, wqe); | ||
| 413 | /* FALLTHROUGH */ | ||
| 414 | case OP(RDMA_WRITE_FIRST): | ||
| 415 | qp->s_state = OP(RDMA_WRITE_MIDDLE); | ||
| 416 | /* FALLTHROUGH */ | ||
| 417 | case OP(RDMA_WRITE_MIDDLE): | ||
| 418 | bth2 = qp->s_psn++ & IPS_PSN_MASK; | ||
| 419 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | ||
| 420 | qp->s_next_psn = qp->s_psn; | ||
| 421 | ss = &qp->s_sge; | ||
| 422 | len = qp->s_len; | ||
| 423 | if (len > pmtu) { | ||
| 424 | /* | ||
| 425 | * Request an ACK every 1/2 MB to avoid retransmit | ||
| 426 | * timeouts. | ||
| 427 | */ | ||
| 428 | if (((wqe->length - len) % (512 * 1024)) == 0) | ||
| 429 | bth2 |= 1 << 31; | ||
| 430 | len = pmtu; | ||
| 431 | break; | ||
| 432 | } | ||
| 433 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE) | ||
| 434 | qp->s_state = OP(RDMA_WRITE_LAST); | ||
| 435 | else { | ||
| 436 | qp->s_state = OP(RDMA_WRITE_LAST_WITH_IMMEDIATE); | ||
| 437 | /* Immediate data comes after the BTH */ | ||
| 438 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 439 | hwords += 1; | ||
| 440 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 441 | bth0 |= 1 << 23; | ||
| 442 | } | ||
| 443 | bth2 |= 1 << 31; /* Request ACK. */ | ||
| 444 | qp->s_cur++; | ||
| 445 | if (qp->s_cur >= qp->s_size) | ||
| 446 | qp->s_cur = 0; | ||
| 447 | break; | ||
| 448 | |||
| 449 | case OP(RDMA_READ_RESPONSE_MIDDLE): | ||
| 450 | /* | ||
| 451 | * This case can only happen if a RDMA read is restarted. | ||
| 452 | * See ipath_restart_rc(). | ||
| 453 | */ | ||
| 454 | ipath_init_restart(qp, wqe); | ||
| 455 | len = ((qp->s_psn - wqe->psn) & IPS_PSN_MASK) * pmtu; | ||
| 456 | ohdr->u.rc.reth.vaddr = | ||
| 457 | cpu_to_be64(wqe->wr.wr.rdma.remote_addr + len); | ||
| 458 | ohdr->u.rc.reth.rkey = | ||
| 459 | cpu_to_be32(wqe->wr.wr.rdma.rkey); | ||
| 460 | ohdr->u.rc.reth.length = cpu_to_be32(qp->s_len); | ||
| 461 | qp->s_state = OP(RDMA_READ_REQUEST); | ||
| 462 | hwords += sizeof(ohdr->u.rc.reth) / 4; | ||
| 463 | bth2 = qp->s_psn++ & IPS_PSN_MASK; | ||
| 464 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | ||
| 465 | qp->s_next_psn = qp->s_psn; | ||
| 466 | ss = NULL; | ||
| 467 | len = 0; | ||
| 468 | qp->s_cur++; | ||
| 469 | if (qp->s_cur == qp->s_size) | ||
| 470 | qp->s_cur = 0; | ||
| 471 | break; | ||
| 472 | |||
| 473 | case OP(RDMA_READ_REQUEST): | ||
| 474 | case OP(COMPARE_SWAP): | ||
| 475 | case OP(FETCH_ADD): | ||
| 476 | /* | ||
| 477 | * We shouldn't start anything new until this request is | ||
| 478 | * finished. The ACK will handle rescheduling us. XXX The | ||
| 479 | * number of outstanding ones is negotiated at connection | ||
| 480 | * setup time (see pg. 258,289)? XXX Also, if we support | ||
| 481 | * multiple outstanding requests, we need to check the WQE | ||
| 482 | * IB_SEND_FENCE flag and not send a new request if a RDMA | ||
| 483 | * read or atomic is pending. | ||
| 484 | */ | ||
| 485 | goto done; | ||
| 486 | } | ||
| 487 | qp->s_len -= len; | ||
| 488 | qp->s_hdrwords = hwords; | ||
| 489 | qp->s_cur_sge = ss; | ||
| 490 | qp->s_cur_size = len; | ||
| 491 | *bth0p = bth0 | (qp->s_state << 24); | ||
| 492 | *bth2p = bth2; | ||
| 493 | return 1; | ||
| 494 | |||
| 495 | done: | ||
| 496 | return 0; | ||
| 497 | } | ||
| 498 | |||
| 499 | static inline void ipath_make_rc_grh(struct ipath_qp *qp, | ||
| 500 | struct ib_global_route *grh, | ||
| 501 | u32 nwords) | ||
| 502 | { | ||
| 503 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 504 | |||
| 505 | /* GRH header size in 32-bit words. */ | ||
| 506 | qp->s_hdrwords += 10; | ||
| 507 | qp->s_hdr.u.l.grh.version_tclass_flow = | ||
| 508 | cpu_to_be32((6 << 28) | | ||
| 509 | (grh->traffic_class << 20) | | ||
| 510 | grh->flow_label); | ||
| 511 | qp->s_hdr.u.l.grh.paylen = | ||
| 512 | cpu_to_be16(((qp->s_hdrwords - 12) + nwords + | ||
| 513 | SIZE_OF_CRC) << 2); | ||
| 514 | /* next_hdr is defined by C8-7 in ch. 8.4.1 */ | ||
| 515 | qp->s_hdr.u.l.grh.next_hdr = 0x1B; | ||
| 516 | qp->s_hdr.u.l.grh.hop_limit = grh->hop_limit; | ||
| 517 | /* The SGID is 32-bit aligned. */ | ||
| 518 | qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = dev->gid_prefix; | ||
| 519 | qp->s_hdr.u.l.grh.sgid.global.interface_id = | ||
| 520 | ipath_layer_get_guid(dev->dd); | ||
| 521 | qp->s_hdr.u.l.grh.dgid = grh->dgid; | ||
| 522 | } | ||
| 523 | |||
| 524 | /** | ||
| 525 | * ipath_do_rc_send - perform a send on an RC QP | ||
| 526 | * @data: contains a pointer to the QP | ||
| 527 | * | ||
| 528 | * Process entries in the send work queue until credit or queue is | ||
| 529 | * exhausted. Only allow one CPU to send a packet per QP (tasklet). | ||
| 530 | * Otherwise, after we drop the QP s_lock, two threads could send | ||
| 531 | * packets out of order. | ||
| 532 | */ | ||
| 533 | void ipath_do_rc_send(unsigned long data) | ||
| 534 | { | ||
| 535 | struct ipath_qp *qp = (struct ipath_qp *)data; | ||
| 536 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 537 | unsigned long flags; | ||
| 538 | u16 lrh0; | ||
| 539 | u32 nwords; | ||
| 540 | u32 extra_bytes; | ||
| 541 | u32 bth0; | ||
| 542 | u32 bth2; | ||
| 543 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
| 544 | struct ipath_other_headers *ohdr; | ||
| 545 | |||
| 546 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags)) | ||
| 547 | goto bail; | ||
| 548 | |||
| 549 | if (unlikely(qp->remote_ah_attr.dlid == | ||
| 550 | ipath_layer_get_lid(dev->dd))) { | ||
| 551 | struct ib_wc wc; | ||
| 552 | |||
| 553 | /* | ||
| 554 | * Pass in an uninitialized ib_wc to be consistent with | ||
| 555 | * other places where ipath_ruc_loopback() is called. | ||
| 556 | */ | ||
| 557 | ipath_ruc_loopback(qp, &wc); | ||
| 558 | goto clear; | ||
| 559 | } | ||
| 560 | |||
| 561 | ohdr = &qp->s_hdr.u.oth; | ||
| 562 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
| 563 | ohdr = &qp->s_hdr.u.l.oth; | ||
| 564 | |||
| 565 | again: | ||
| 566 | /* Check for a constructed packet to be sent. */ | ||
| 567 | if (qp->s_hdrwords != 0) { | ||
| 568 | /* | ||
| 569 | * If no PIO bufs are available, return. An interrupt will | ||
| 570 | * call ipath_ib_piobufavail() when one is available. | ||
| 571 | */ | ||
| 572 | _VERBS_INFO("h %u %p\n", qp->s_hdrwords, &qp->s_hdr); | ||
| 573 | _VERBS_INFO("d %u %p %u %p %u %u %u %u\n", qp->s_cur_size, | ||
| 574 | qp->s_cur_sge->sg_list, | ||
| 575 | qp->s_cur_sge->num_sge, | ||
| 576 | qp->s_cur_sge->sge.vaddr, | ||
| 577 | qp->s_cur_sge->sge.sge_length, | ||
| 578 | qp->s_cur_sge->sge.length, | ||
| 579 | qp->s_cur_sge->sge.m, | ||
| 580 | qp->s_cur_sge->sge.n); | ||
| 581 | if (ipath_verbs_send(dev->dd, qp->s_hdrwords, | ||
| 582 | (u32 *) &qp->s_hdr, qp->s_cur_size, | ||
| 583 | qp->s_cur_sge)) { | ||
| 584 | ipath_no_bufs_available(qp, dev); | ||
| 585 | goto bail; | ||
| 586 | } | ||
| 587 | dev->n_unicast_xmit++; | ||
| 588 | /* Record that we sent the packet and s_hdr is empty. */ | ||
| 589 | qp->s_hdrwords = 0; | ||
| 590 | } | ||
| 591 | |||
| 592 | /* | ||
| 593 | * The lock is needed to synchronize between setting | ||
| 594 | * qp->s_ack_state, resend timer, and post_send(). | ||
| 595 | */ | ||
| 596 | spin_lock_irqsave(&qp->s_lock, flags); | ||
| 597 | |||
| 598 | /* Sending responses has higher priority over sending requests. */ | ||
| 599 | if (qp->s_ack_state != OP(ACKNOWLEDGE) && | ||
| 600 | (bth0 = ipath_make_rc_ack(qp, ohdr, pmtu)) != 0) | ||
| 601 | bth2 = qp->s_ack_psn++ & IPS_PSN_MASK; | ||
| 602 | else if (!ipath_make_rc_req(qp, ohdr, pmtu, &bth0, &bth2)) | ||
| 603 | goto done; | ||
| 604 | |||
| 605 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 606 | |||
| 607 | /* Construct the header. */ | ||
| 608 | extra_bytes = (4 - qp->s_cur_size) & 3; | ||
| 609 | nwords = (qp->s_cur_size + extra_bytes) >> 2; | ||
| 610 | lrh0 = IPS_LRH_BTH; | ||
| 611 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
| 612 | ipath_make_rc_grh(qp, &qp->remote_ah_attr.grh, nwords); | ||
| 613 | lrh0 = IPS_LRH_GRH; | ||
| 614 | } | ||
| 615 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
| 616 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
| 617 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
| 618 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + | ||
| 619 | SIZE_OF_CRC); | ||
| 620 | qp->s_hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd)); | ||
| 621 | bth0 |= ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); | ||
| 622 | bth0 |= extra_bytes << 20; | ||
| 623 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
| 624 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
| 625 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
| 626 | |||
| 627 | /* Check for more work to do. */ | ||
| 628 | goto again; | ||
| 629 | |||
| 630 | done: | ||
| 631 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 632 | clear: | ||
| 633 | clear_bit(IPATH_S_BUSY, &qp->s_flags); | ||
| 634 | bail: | ||
| 635 | return; | ||
| 636 | } | ||
| 637 | |||
| 638 | static void send_rc_ack(struct ipath_qp *qp) | ||
| 639 | { | ||
| 640 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 641 | u16 lrh0; | ||
| 642 | u32 bth0; | ||
| 643 | struct ipath_other_headers *ohdr; | ||
| 644 | |||
| 645 | /* Construct the header. */ | ||
| 646 | ohdr = &qp->s_hdr.u.oth; | ||
| 647 | lrh0 = IPS_LRH_BTH; | ||
| 648 | /* header size in 32-bit words LRH+BTH+AETH = (8+12+4)/4. */ | ||
| 649 | qp->s_hdrwords = 6; | ||
| 650 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
| 651 | ipath_make_rc_grh(qp, &qp->remote_ah_attr.grh, 0); | ||
| 652 | ohdr = &qp->s_hdr.u.l.oth; | ||
| 653 | lrh0 = IPS_LRH_GRH; | ||
| 654 | } | ||
| 655 | bth0 = ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); | ||
| 656 | ohdr->u.aeth = ipath_compute_aeth(qp); | ||
| 657 | if (qp->s_ack_state >= OP(COMPARE_SWAP)) { | ||
| 658 | bth0 |= IB_OPCODE_ATOMIC_ACKNOWLEDGE << 24; | ||
| 659 | ohdr->u.at.atomic_ack_eth = cpu_to_be64(qp->s_ack_atomic); | ||
| 660 | qp->s_hdrwords += sizeof(ohdr->u.at.atomic_ack_eth) / 4; | ||
| 661 | } | ||
| 662 | else | ||
| 663 | bth0 |= OP(ACKNOWLEDGE) << 24; | ||
| 664 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
| 665 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
| 666 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
| 667 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + SIZE_OF_CRC); | ||
| 668 | qp->s_hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd)); | ||
| 669 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
| 670 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
| 671 | ohdr->bth[2] = cpu_to_be32(qp->s_ack_psn & IPS_PSN_MASK); | ||
| 672 | |||
| 673 | /* | ||
| 674 | * If we can send the ACK, clear the ACK state. | ||
| 675 | */ | ||
| 676 | if (ipath_verbs_send(dev->dd, qp->s_hdrwords, (u32 *) &qp->s_hdr, | ||
| 677 | 0, NULL) == 0) { | ||
| 678 | qp->s_ack_state = OP(ACKNOWLEDGE); | ||
| 679 | dev->n_rc_qacks++; | ||
| 680 | dev->n_unicast_xmit++; | ||
| 681 | } | ||
| 682 | } | ||
| 683 | |||
| 684 | /** | ||
| 685 | * ipath_restart_rc - back up requester to resend the last un-ACKed request | ||
| 686 | * @qp: the QP to restart | ||
| 687 | * @psn: packet sequence number for the request | ||
| 688 | * @wc: the work completion request | ||
| 689 | * | ||
| 690 | * The QP s_lock should be held. | ||
| 691 | */ | ||
| 692 | void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | ||
| 693 | { | ||
| 694 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 695 | struct ipath_ibdev *dev; | ||
| 696 | u32 n; | ||
| 697 | |||
| 698 | /* | ||
| 699 | * If there are no requests pending, we are done. | ||
| 700 | */ | ||
| 701 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0 || | ||
| 702 | qp->s_last == qp->s_tail) | ||
| 703 | goto done; | ||
| 704 | |||
| 705 | if (qp->s_retry == 0) { | ||
| 706 | wc->wr_id = wqe->wr.wr_id; | ||
| 707 | wc->status = IB_WC_RETRY_EXC_ERR; | ||
| 708 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 709 | wc->vendor_err = 0; | ||
| 710 | wc->byte_len = 0; | ||
| 711 | wc->qp_num = qp->ibqp.qp_num; | ||
| 712 | wc->src_qp = qp->remote_qpn; | ||
| 713 | wc->pkey_index = 0; | ||
| 714 | wc->slid = qp->remote_ah_attr.dlid; | ||
| 715 | wc->sl = qp->remote_ah_attr.sl; | ||
| 716 | wc->dlid_path_bits = 0; | ||
| 717 | wc->port_num = 0; | ||
| 718 | ipath_sqerror_qp(qp, wc); | ||
| 719 | goto bail; | ||
| 720 | } | ||
| 721 | qp->s_retry--; | ||
| 722 | |||
| 723 | /* | ||
| 724 | * Remove the QP from the timeout queue. | ||
| 725 | * Note: it may already have been removed by ipath_ib_timer(). | ||
| 726 | */ | ||
| 727 | dev = to_idev(qp->ibqp.device); | ||
| 728 | spin_lock(&dev->pending_lock); | ||
| 729 | if (qp->timerwait.next != LIST_POISON1) | ||
| 730 | list_del(&qp->timerwait); | ||
| 731 | spin_unlock(&dev->pending_lock); | ||
| 732 | |||
| 733 | if (wqe->wr.opcode == IB_WR_RDMA_READ) | ||
| 734 | dev->n_rc_resends++; | ||
| 735 | else | ||
| 736 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; | ||
| 737 | |||
| 738 | /* | ||
| 739 | * If we are starting the request from the beginning, let the normal | ||
| 740 | * send code handle initialization. | ||
| 741 | */ | ||
| 742 | qp->s_cur = qp->s_last; | ||
| 743 | if (ipath_cmp24(psn, wqe->psn) <= 0) { | ||
| 744 | qp->s_state = OP(SEND_LAST); | ||
| 745 | qp->s_psn = wqe->psn; | ||
| 746 | } else { | ||
| 747 | n = qp->s_cur; | ||
| 748 | for (;;) { | ||
| 749 | if (++n == qp->s_size) | ||
| 750 | n = 0; | ||
| 751 | if (n == qp->s_tail) { | ||
| 752 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0) { | ||
| 753 | qp->s_cur = n; | ||
| 754 | wqe = get_swqe_ptr(qp, n); | ||
| 755 | } | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | wqe = get_swqe_ptr(qp, n); | ||
| 759 | if (ipath_cmp24(psn, wqe->psn) < 0) | ||
| 760 | break; | ||
| 761 | qp->s_cur = n; | ||
| 762 | } | ||
| 763 | qp->s_psn = psn; | ||
| 764 | |||
| 765 | /* | ||
| 766 | * Reset the state to restart in the middle of a request. | ||
| 767 | * Don't change the s_sge, s_cur_sge, or s_cur_size. | ||
| 768 | * See ipath_do_rc_send(). | ||
| 769 | */ | ||
| 770 | switch (wqe->wr.opcode) { | ||
| 771 | case IB_WR_SEND: | ||
| 772 | case IB_WR_SEND_WITH_IMM: | ||
| 773 | qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
| 774 | break; | ||
| 775 | |||
| 776 | case IB_WR_RDMA_WRITE: | ||
| 777 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
| 778 | qp->s_state = OP(RDMA_READ_RESPONSE_LAST); | ||
| 779 | break; | ||
| 780 | |||
| 781 | case IB_WR_RDMA_READ: | ||
| 782 | qp->s_state = | ||
| 783 | OP(RDMA_READ_RESPONSE_MIDDLE); | ||
| 784 | break; | ||
| 785 | |||
| 786 | default: | ||
| 787 | /* | ||
| 788 | * This case shouldn't happen since its only | ||
| 789 | * one PSN per req. | ||
| 790 | */ | ||
| 791 | qp->s_state = OP(SEND_LAST); | ||
| 792 | } | ||
| 793 | } | ||
| 794 | |||
| 795 | done: | ||
| 796 | tasklet_hi_schedule(&qp->s_task); | ||
| 797 | |||
| 798 | bail: | ||
| 799 | return; | ||
| 800 | } | ||
| 801 | |||
| 802 | /** | ||
| 803 | * reset_psn - reset the QP state to send starting from PSN | ||
| 804 | * @qp: the QP | ||
| 805 | * @psn: the packet sequence number to restart at | ||
| 806 | * | ||
| 807 | * This is called from ipath_rc_rcv() to process an incoming RC ACK | ||
| 808 | * for the given QP. | ||
| 809 | * Called at interrupt level with the QP s_lock held. | ||
| 810 | */ | ||
| 811 | static void reset_psn(struct ipath_qp *qp, u32 psn) | ||
| 812 | { | ||
| 813 | struct ipath_swqe *wqe; | ||
| 814 | u32 n; | ||
| 815 | |||
| 816 | n = qp->s_cur; | ||
| 817 | wqe = get_swqe_ptr(qp, n); | ||
| 818 | for (;;) { | ||
| 819 | if (++n == qp->s_size) | ||
| 820 | n = 0; | ||
| 821 | if (n == qp->s_tail) { | ||
| 822 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0) { | ||
| 823 | qp->s_cur = n; | ||
| 824 | wqe = get_swqe_ptr(qp, n); | ||
| 825 | } | ||
| 826 | break; | ||
| 827 | } | ||
| 828 | wqe = get_swqe_ptr(qp, n); | ||
| 829 | if (ipath_cmp24(psn, wqe->psn) < 0) | ||
| 830 | break; | ||
| 831 | qp->s_cur = n; | ||
| 832 | } | ||
| 833 | qp->s_psn = psn; | ||
| 834 | |||
| 835 | /* | ||
| 836 | * Set the state to restart in the middle of a | ||
| 837 | * request. Don't change the s_sge, s_cur_sge, or | ||
| 838 | * s_cur_size. See ipath_do_rc_send(). | ||
| 839 | */ | ||
| 840 | switch (wqe->wr.opcode) { | ||
| 841 | case IB_WR_SEND: | ||
| 842 | case IB_WR_SEND_WITH_IMM: | ||
| 843 | qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
| 844 | break; | ||
| 845 | |||
| 846 | case IB_WR_RDMA_WRITE: | ||
| 847 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
| 848 | qp->s_state = OP(RDMA_READ_RESPONSE_LAST); | ||
| 849 | break; | ||
| 850 | |||
| 851 | case IB_WR_RDMA_READ: | ||
| 852 | qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE); | ||
| 853 | break; | ||
| 854 | |||
| 855 | default: | ||
| 856 | /* | ||
| 857 | * This case shouldn't happen since its only | ||
| 858 | * one PSN per req. | ||
| 859 | */ | ||
| 860 | qp->s_state = OP(SEND_LAST); | ||
| 861 | } | ||
| 862 | } | ||
| 863 | |||
| 864 | /** | ||
| 865 | * do_rc_ack - process an incoming RC ACK | ||
| 866 | * @qp: the QP the ACK came in on | ||
| 867 | * @psn: the packet sequence number of the ACK | ||
| 868 | * @opcode: the opcode of the request that resulted in the ACK | ||
| 869 | * | ||
| 870 | * This is called from ipath_rc_rcv() to process an incoming RC ACK | ||
| 871 | * for the given QP. | ||
| 872 | * Called at interrupt level with the QP s_lock held. | ||
| 873 | * Returns 1 if OK, 0 if current operation should be aborted (NAK). | ||
| 874 | */ | ||
| 875 | static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | ||
| 876 | { | ||
| 877 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 878 | struct ib_wc wc; | ||
| 879 | struct ipath_swqe *wqe; | ||
| 880 | int ret = 0; | ||
| 881 | |||
| 882 | /* | ||
| 883 | * Remove the QP from the timeout queue (or RNR timeout queue). | ||
| 884 | * If ipath_ib_timer() has already removed it, | ||
| 885 | * it's OK since we hold the QP s_lock and ipath_restart_rc() | ||
| 886 | * just won't find anything to restart if we ACK everything. | ||
| 887 | */ | ||
| 888 | spin_lock(&dev->pending_lock); | ||
| 889 | if (qp->timerwait.next != LIST_POISON1) | ||
| 890 | list_del(&qp->timerwait); | ||
| 891 | spin_unlock(&dev->pending_lock); | ||
| 892 | |||
| 893 | /* | ||
| 894 | * Note that NAKs implicitly ACK outstanding SEND and RDMA write | ||
| 895 | * requests and implicitly NAK RDMA read and atomic requests issued | ||
| 896 | * before the NAK'ed request. The MSN won't include the NAK'ed | ||
| 897 | * request but will include an ACK'ed request(s). | ||
| 898 | */ | ||
| 899 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 900 | |||
| 901 | /* Nothing is pending to ACK/NAK. */ | ||
| 902 | if (qp->s_last == qp->s_tail) | ||
| 903 | goto bail; | ||
| 904 | |||
| 905 | /* | ||
| 906 | * The MSN might be for a later WQE than the PSN indicates so | ||
| 907 | * only complete WQEs that the PSN finishes. | ||
| 908 | */ | ||
| 909 | while (ipath_cmp24(psn, wqe->lpsn) >= 0) { | ||
| 910 | /* If we are ACKing a WQE, the MSN should be >= the SSN. */ | ||
| 911 | if (ipath_cmp24(aeth, wqe->ssn) < 0) | ||
| 912 | break; | ||
| 913 | /* | ||
| 914 | * If this request is a RDMA read or atomic, and the ACK is | ||
| 915 | * for a later operation, this ACK NAKs the RDMA read or | ||
| 916 | * atomic. In other words, only a RDMA_READ_LAST or ONLY | ||
| 917 | * can ACK a RDMA read and likewise for atomic ops. Note | ||
| 918 | * that the NAK case can only happen if relaxed ordering is | ||
| 919 | * used and requests are sent after an RDMA read or atomic | ||
| 920 | * is sent but before the response is received. | ||
| 921 | */ | ||
| 922 | if ((wqe->wr.opcode == IB_WR_RDMA_READ && | ||
| 923 | opcode != OP(RDMA_READ_RESPONSE_LAST)) || | ||
| 924 | ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || | ||
| 925 | wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) && | ||
| 926 | (opcode != OP(ATOMIC_ACKNOWLEDGE) || | ||
| 927 | ipath_cmp24(wqe->psn, psn) != 0))) { | ||
| 928 | /* | ||
| 929 | * The last valid PSN seen is the previous | ||
| 930 | * request's. | ||
| 931 | */ | ||
| 932 | qp->s_last_psn = wqe->psn - 1; | ||
| 933 | /* Retry this request. */ | ||
| 934 | ipath_restart_rc(qp, wqe->psn, &wc); | ||
| 935 | /* | ||
| 936 | * No need to process the ACK/NAK since we are | ||
| 937 | * restarting an earlier request. | ||
| 938 | */ | ||
| 939 | goto bail; | ||
| 940 | } | ||
| 941 | /* Post a send completion queue entry if requested. */ | ||
| 942 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) || | ||
| 943 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
| 944 | wc.wr_id = wqe->wr.wr_id; | ||
| 945 | wc.status = IB_WC_SUCCESS; | ||
| 946 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 947 | wc.vendor_err = 0; | ||
| 948 | wc.byte_len = wqe->length; | ||
| 949 | wc.qp_num = qp->ibqp.qp_num; | ||
| 950 | wc.src_qp = qp->remote_qpn; | ||
| 951 | wc.pkey_index = 0; | ||
| 952 | wc.slid = qp->remote_ah_attr.dlid; | ||
| 953 | wc.sl = qp->remote_ah_attr.sl; | ||
| 954 | wc.dlid_path_bits = 0; | ||
| 955 | wc.port_num = 0; | ||
| 956 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
| 957 | } | ||
| 958 | qp->s_retry = qp->s_retry_cnt; | ||
| 959 | /* | ||
| 960 | * If we are completing a request which is in the process of | ||
| 961 | * being resent, we can stop resending it since we know the | ||
| 962 | * responder has already seen it. | ||
| 963 | */ | ||
| 964 | if (qp->s_last == qp->s_cur) { | ||
| 965 | if (++qp->s_cur >= qp->s_size) | ||
| 966 | qp->s_cur = 0; | ||
| 967 | wqe = get_swqe_ptr(qp, qp->s_cur); | ||
| 968 | qp->s_state = OP(SEND_LAST); | ||
| 969 | qp->s_psn = wqe->psn; | ||
| 970 | } | ||
| 971 | if (++qp->s_last >= qp->s_size) | ||
| 972 | qp->s_last = 0; | ||
| 973 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 974 | if (qp->s_last == qp->s_tail) | ||
| 975 | break; | ||
| 976 | } | ||
| 977 | |||
| 978 | switch (aeth >> 29) { | ||
| 979 | case 0: /* ACK */ | ||
| 980 | dev->n_rc_acks++; | ||
| 981 | /* If this is a partial ACK, reset the retransmit timer. */ | ||
| 982 | if (qp->s_last != qp->s_tail) { | ||
| 983 | spin_lock(&dev->pending_lock); | ||
| 984 | list_add_tail(&qp->timerwait, | ||
| 985 | &dev->pending[dev->pending_index]); | ||
| 986 | spin_unlock(&dev->pending_lock); | ||
| 987 | } | ||
| 988 | ipath_get_credit(qp, aeth); | ||
| 989 | qp->s_rnr_retry = qp->s_rnr_retry_cnt; | ||
| 990 | qp->s_retry = qp->s_retry_cnt; | ||
| 991 | qp->s_last_psn = psn; | ||
| 992 | ret = 1; | ||
| 993 | goto bail; | ||
| 994 | |||
| 995 | case 1: /* RNR NAK */ | ||
| 996 | dev->n_rnr_naks++; | ||
| 997 | if (qp->s_rnr_retry == 0) { | ||
| 998 | if (qp->s_last == qp->s_tail) | ||
| 999 | goto bail; | ||
| 1000 | |||
| 1001 | wc.status = IB_WC_RNR_RETRY_EXC_ERR; | ||
| 1002 | goto class_b; | ||
| 1003 | } | ||
| 1004 | if (qp->s_rnr_retry_cnt < 7) | ||
| 1005 | qp->s_rnr_retry--; | ||
| 1006 | if (qp->s_last == qp->s_tail) | ||
| 1007 | goto bail; | ||
| 1008 | |||
| 1009 | /* The last valid PSN seen is the previous request's. */ | ||
| 1010 | qp->s_last_psn = wqe->psn - 1; | ||
| 1011 | |||
| 1012 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; | ||
| 1013 | |||
| 1014 | /* | ||
| 1015 | * If we are starting the request from the beginning, let | ||
| 1016 | * the normal send code handle initialization. | ||
| 1017 | */ | ||
| 1018 | qp->s_cur = qp->s_last; | ||
| 1019 | wqe = get_swqe_ptr(qp, qp->s_cur); | ||
| 1020 | if (ipath_cmp24(psn, wqe->psn) <= 0) { | ||
| 1021 | qp->s_state = OP(SEND_LAST); | ||
| 1022 | qp->s_psn = wqe->psn; | ||
| 1023 | } else | ||
| 1024 | reset_psn(qp, psn); | ||
| 1025 | |||
| 1026 | qp->s_rnr_timeout = | ||
| 1027 | ib_ipath_rnr_table[(aeth >> IPS_AETH_CREDIT_SHIFT) & | ||
| 1028 | IPS_AETH_CREDIT_MASK]; | ||
| 1029 | ipath_insert_rnr_queue(qp); | ||
| 1030 | goto bail; | ||
| 1031 | |||
| 1032 | case 3: /* NAK */ | ||
| 1033 | /* The last valid PSN seen is the previous request's. */ | ||
| 1034 | if (qp->s_last != qp->s_tail) | ||
| 1035 | qp->s_last_psn = wqe->psn - 1; | ||
| 1036 | switch ((aeth >> IPS_AETH_CREDIT_SHIFT) & | ||
| 1037 | IPS_AETH_CREDIT_MASK) { | ||
| 1038 | case 0: /* PSN sequence error */ | ||
| 1039 | dev->n_seq_naks++; | ||
| 1040 | /* | ||
| 1041 | * Back up to the responder's expected PSN. XXX | ||
| 1042 | * Note that we might get a NAK in the middle of an | ||
| 1043 | * RDMA READ response which terminates the RDMA | ||
| 1044 | * READ. | ||
| 1045 | */ | ||
| 1046 | if (qp->s_last == qp->s_tail) | ||
| 1047 | break; | ||
| 1048 | |||
| 1049 | if (ipath_cmp24(psn, wqe->psn) < 0) | ||
| 1050 | break; | ||
| 1051 | |||
| 1052 | /* Retry the request. */ | ||
| 1053 | ipath_restart_rc(qp, psn, &wc); | ||
| 1054 | break; | ||
| 1055 | |||
| 1056 | case 1: /* Invalid Request */ | ||
| 1057 | wc.status = IB_WC_REM_INV_REQ_ERR; | ||
| 1058 | dev->n_other_naks++; | ||
| 1059 | goto class_b; | ||
| 1060 | |||
| 1061 | case 2: /* Remote Access Error */ | ||
| 1062 | wc.status = IB_WC_REM_ACCESS_ERR; | ||
| 1063 | dev->n_other_naks++; | ||
| 1064 | goto class_b; | ||
| 1065 | |||
| 1066 | case 3: /* Remote Operation Error */ | ||
| 1067 | wc.status = IB_WC_REM_OP_ERR; | ||
| 1068 | dev->n_other_naks++; | ||
| 1069 | class_b: | ||
| 1070 | wc.wr_id = wqe->wr.wr_id; | ||
| 1071 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 1072 | wc.vendor_err = 0; | ||
| 1073 | wc.byte_len = 0; | ||
| 1074 | wc.qp_num = qp->ibqp.qp_num; | ||
| 1075 | wc.src_qp = qp->remote_qpn; | ||
| 1076 | wc.pkey_index = 0; | ||
| 1077 | wc.slid = qp->remote_ah_attr.dlid; | ||
| 1078 | wc.sl = qp->remote_ah_attr.sl; | ||
| 1079 | wc.dlid_path_bits = 0; | ||
| 1080 | wc.port_num = 0; | ||
| 1081 | ipath_sqerror_qp(qp, &wc); | ||
| 1082 | break; | ||
| 1083 | |||
| 1084 | default: | ||
| 1085 | /* Ignore other reserved NAK error codes */ | ||
| 1086 | goto reserved; | ||
| 1087 | } | ||
| 1088 | qp->s_rnr_retry = qp->s_rnr_retry_cnt; | ||
| 1089 | goto bail; | ||
| 1090 | |||
| 1091 | default: /* 2: reserved */ | ||
| 1092 | reserved: | ||
| 1093 | /* Ignore reserved NAK codes. */ | ||
| 1094 | goto bail; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | bail: | ||
| 1098 | return ret; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | /** | ||
| 1102 | * ipath_rc_rcv_resp - process an incoming RC response packet | ||
| 1103 | * @dev: the device this packet came in on | ||
| 1104 | * @ohdr: the other headers for this packet | ||
| 1105 | * @data: the packet data | ||
| 1106 | * @tlen: the packet length | ||
| 1107 | * @qp: the QP for this packet | ||
| 1108 | * @opcode: the opcode for this packet | ||
| 1109 | * @psn: the packet sequence number for this packet | ||
| 1110 | * @hdrsize: the header length | ||
| 1111 | * @pmtu: the path MTU | ||
| 1112 | * @header_in_data: true if part of the header data is in the data buffer | ||
| 1113 | * | ||
| 1114 | * This is called from ipath_rc_rcv() to process an incoming RC response | ||
| 1115 | * packet for the given QP. | ||
| 1116 | * Called at interrupt level. | ||
| 1117 | */ | ||
| 1118 | static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, | ||
| 1119 | struct ipath_other_headers *ohdr, | ||
| 1120 | void *data, u32 tlen, | ||
| 1121 | struct ipath_qp *qp, | ||
| 1122 | u32 opcode, | ||
| 1123 | u32 psn, u32 hdrsize, u32 pmtu, | ||
| 1124 | int header_in_data) | ||
| 1125 | { | ||
| 1126 | unsigned long flags; | ||
| 1127 | struct ib_wc wc; | ||
| 1128 | int diff; | ||
| 1129 | u32 pad; | ||
| 1130 | u32 aeth; | ||
| 1131 | |||
| 1132 | spin_lock_irqsave(&qp->s_lock, flags); | ||
| 1133 | |||
| 1134 | /* Ignore invalid responses. */ | ||
| 1135 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0) | ||
| 1136 | goto ack_done; | ||
| 1137 | |||
| 1138 | /* Ignore duplicate responses. */ | ||
| 1139 | diff = ipath_cmp24(psn, qp->s_last_psn); | ||
| 1140 | if (unlikely(diff <= 0)) { | ||
| 1141 | /* Update credits for "ghost" ACKs */ | ||
| 1142 | if (diff == 0 && opcode == OP(ACKNOWLEDGE)) { | ||
| 1143 | if (!header_in_data) | ||
| 1144 | aeth = be32_to_cpu(ohdr->u.aeth); | ||
| 1145 | else { | ||
| 1146 | aeth = be32_to_cpu(((__be32 *) data)[0]); | ||
| 1147 | data += sizeof(__be32); | ||
| 1148 | } | ||
| 1149 | if ((aeth >> 29) == 0) | ||
| 1150 | ipath_get_credit(qp, aeth); | ||
| 1151 | } | ||
| 1152 | goto ack_done; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | switch (opcode) { | ||
| 1156 | case OP(ACKNOWLEDGE): | ||
| 1157 | case OP(ATOMIC_ACKNOWLEDGE): | ||
| 1158 | case OP(RDMA_READ_RESPONSE_FIRST): | ||
| 1159 | if (!header_in_data) | ||
| 1160 | aeth = be32_to_cpu(ohdr->u.aeth); | ||
| 1161 | else { | ||
| 1162 | aeth = be32_to_cpu(((__be32 *) data)[0]); | ||
| 1163 | data += sizeof(__be32); | ||
| 1164 | } | ||
| 1165 | if (opcode == OP(ATOMIC_ACKNOWLEDGE)) | ||
| 1166 | *(u64 *) qp->s_sge.sge.vaddr = *(u64 *) data; | ||
| 1167 | if (!do_rc_ack(qp, aeth, psn, opcode) || | ||
| 1168 | opcode != OP(RDMA_READ_RESPONSE_FIRST)) | ||
| 1169 | goto ack_done; | ||
| 1170 | hdrsize += 4; | ||
| 1171 | /* | ||
| 1172 | * do_rc_ack() has already checked the PSN so skip | ||
| 1173 | * the sequence check. | ||
| 1174 | */ | ||
| 1175 | goto rdma_read; | ||
| 1176 | |||
| 1177 | case OP(RDMA_READ_RESPONSE_MIDDLE): | ||
| 1178 | /* no AETH, no ACK */ | ||
| 1179 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { | ||
| 1180 | dev->n_rdma_seq++; | ||
| 1181 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | ||
| 1182 | goto ack_done; | ||
| 1183 | } | ||
| 1184 | rdma_read: | ||
| 1185 | if (unlikely(qp->s_state != OP(RDMA_READ_REQUEST))) | ||
| 1186 | goto ack_done; | ||
| 1187 | if (unlikely(tlen != (hdrsize + pmtu + 4))) | ||
| 1188 | goto ack_done; | ||
| 1189 | if (unlikely(pmtu >= qp->s_len)) | ||
| 1190 | goto ack_done; | ||
| 1191 | /* We got a response so update the timeout. */ | ||
| 1192 | if (unlikely(qp->s_last == qp->s_tail || | ||
| 1193 | get_swqe_ptr(qp, qp->s_last)->wr.opcode != | ||
| 1194 | IB_WR_RDMA_READ)) | ||
| 1195 | goto ack_done; | ||
| 1196 | spin_lock(&dev->pending_lock); | ||
| 1197 | if (qp->s_rnr_timeout == 0 && | ||
| 1198 | qp->timerwait.next != LIST_POISON1) | ||
| 1199 | list_move_tail(&qp->timerwait, | ||
| 1200 | &dev->pending[dev->pending_index]); | ||
| 1201 | spin_unlock(&dev->pending_lock); | ||
| 1202 | /* | ||
| 1203 | * Update the RDMA receive state but do the copy w/o holding the | ||
| 1204 | * locks and blocking interrupts. XXX Yet another place that | ||
| 1205 | * affects relaxed RDMA order since we don't want s_sge modified. | ||
| 1206 | */ | ||
| 1207 | qp->s_len -= pmtu; | ||
| 1208 | qp->s_last_psn = psn; | ||
| 1209 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 1210 | ipath_copy_sge(&qp->s_sge, data, pmtu); | ||
| 1211 | goto bail; | ||
| 1212 | |||
| 1213 | case OP(RDMA_READ_RESPONSE_LAST): | ||
| 1214 | /* ACKs READ req. */ | ||
| 1215 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { | ||
| 1216 | dev->n_rdma_seq++; | ||
| 1217 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | ||
| 1218 | goto ack_done; | ||
| 1219 | } | ||
| 1220 | /* FALLTHROUGH */ | ||
| 1221 | case OP(RDMA_READ_RESPONSE_ONLY): | ||
| 1222 | if (unlikely(qp->s_state != OP(RDMA_READ_REQUEST))) | ||
| 1223 | goto ack_done; | ||
| 1224 | /* | ||
| 1225 | * Get the number of bytes the message was padded by. | ||
| 1226 | */ | ||
| 1227 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 1228 | /* | ||
| 1229 | * Check that the data size is >= 1 && <= pmtu. | ||
| 1230 | * Remember to account for the AETH header (4) and | ||
| 1231 | * ICRC (4). | ||
| 1232 | */ | ||
| 1233 | if (unlikely(tlen <= (hdrsize + pad + 8))) { | ||
| 1234 | /* | ||
| 1235 | * XXX Need to generate an error CQ | ||
| 1236 | * entry. | ||
| 1237 | */ | ||
| 1238 | goto ack_done; | ||
| 1239 | } | ||
| 1240 | tlen -= hdrsize + pad + 8; | ||
| 1241 | if (unlikely(tlen != qp->s_len)) { | ||
| 1242 | /* | ||
| 1243 | * XXX Need to generate an error CQ | ||
| 1244 | * entry. | ||
| 1245 | */ | ||
| 1246 | goto ack_done; | ||
| 1247 | } | ||
| 1248 | if (!header_in_data) | ||
| 1249 | aeth = be32_to_cpu(ohdr->u.aeth); | ||
| 1250 | else { | ||
| 1251 | aeth = be32_to_cpu(((__be32 *) data)[0]); | ||
| 1252 | data += sizeof(__be32); | ||
| 1253 | } | ||
| 1254 | ipath_copy_sge(&qp->s_sge, data, tlen); | ||
| 1255 | if (do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST))) { | ||
| 1256 | /* | ||
| 1257 | * Change the state so we contimue | ||
| 1258 | * processing new requests. | ||
| 1259 | */ | ||
| 1260 | qp->s_state = OP(SEND_LAST); | ||
| 1261 | } | ||
| 1262 | goto ack_done; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | ack_done: | ||
| 1266 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 1267 | bail: | ||
| 1268 | return; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | /** | ||
| 1272 | * ipath_rc_rcv_error - process an incoming duplicate or error RC packet | ||
| 1273 | * @dev: the device this packet came in on | ||
| 1274 | * @ohdr: the other headers for this packet | ||
| 1275 | * @data: the packet data | ||
| 1276 | * @qp: the QP for this packet | ||
| 1277 | * @opcode: the opcode for this packet | ||
| 1278 | * @psn: the packet sequence number for this packet | ||
| 1279 | * @diff: the difference between the PSN and the expected PSN | ||
| 1280 | * @header_in_data: true if part of the header data is in the data buffer | ||
| 1281 | * | ||
| 1282 | * This is called from ipath_rc_rcv() to process an unexpected | ||
| 1283 | * incoming RC packet for the given QP. | ||
| 1284 | * Called at interrupt level. | ||
| 1285 | * Return 1 if no more processing is needed; otherwise return 0 to | ||
| 1286 | * schedule a response to be sent and the s_lock unlocked. | ||
| 1287 | */ | ||
| 1288 | static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, | ||
| 1289 | struct ipath_other_headers *ohdr, | ||
| 1290 | void *data, | ||
| 1291 | struct ipath_qp *qp, | ||
| 1292 | u32 opcode, | ||
| 1293 | u32 psn, | ||
| 1294 | int diff, | ||
| 1295 | int header_in_data) | ||
| 1296 | { | ||
| 1297 | struct ib_reth *reth; | ||
| 1298 | |||
| 1299 | if (diff > 0) { | ||
| 1300 | /* | ||
| 1301 | * Packet sequence error. | ||
| 1302 | * A NAK will ACK earlier sends and RDMA writes. | ||
| 1303 | * Don't queue the NAK if a RDMA read, atomic, or | ||
| 1304 | * NAK is pending though. | ||
| 1305 | */ | ||
| 1306 | spin_lock(&qp->s_lock); | ||
| 1307 | if ((qp->s_ack_state >= OP(RDMA_READ_REQUEST) && | ||
| 1308 | qp->s_ack_state != IB_OPCODE_ACKNOWLEDGE) || | ||
| 1309 | qp->s_nak_state != 0) { | ||
| 1310 | spin_unlock(&qp->s_lock); | ||
| 1311 | goto done; | ||
| 1312 | } | ||
| 1313 | qp->s_ack_state = OP(SEND_ONLY); | ||
| 1314 | qp->s_nak_state = IB_NAK_PSN_ERROR; | ||
| 1315 | /* Use the expected PSN. */ | ||
| 1316 | qp->s_ack_psn = qp->r_psn; | ||
| 1317 | goto resched; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | /* | ||
| 1321 | * Handle a duplicate request. Don't re-execute SEND, RDMA | ||
| 1322 | * write or atomic op. Don't NAK errors, just silently drop | ||
| 1323 | * the duplicate request. Note that r_sge, r_len, and | ||
| 1324 | * r_rcv_len may be in use so don't modify them. | ||
| 1325 | * | ||
| 1326 | * We are supposed to ACK the earliest duplicate PSN but we | ||
| 1327 | * can coalesce an outstanding duplicate ACK. We have to | ||
| 1328 | * send the earliest so that RDMA reads can be restarted at | ||
| 1329 | * the requester's expected PSN. | ||
| 1330 | */ | ||
| 1331 | spin_lock(&qp->s_lock); | ||
| 1332 | if (qp->s_ack_state != IB_OPCODE_ACKNOWLEDGE && | ||
| 1333 | ipath_cmp24(psn, qp->s_ack_psn) >= 0) { | ||
| 1334 | if (qp->s_ack_state < IB_OPCODE_RDMA_READ_REQUEST) | ||
| 1335 | qp->s_ack_psn = psn; | ||
| 1336 | spin_unlock(&qp->s_lock); | ||
| 1337 | goto done; | ||
| 1338 | } | ||
| 1339 | switch (opcode) { | ||
| 1340 | case OP(RDMA_READ_REQUEST): | ||
| 1341 | /* | ||
| 1342 | * We have to be careful to not change s_rdma_sge | ||
| 1343 | * while ipath_do_rc_send() is using it and not | ||
| 1344 | * holding the s_lock. | ||
| 1345 | */ | ||
| 1346 | if (qp->s_ack_state != OP(ACKNOWLEDGE) && | ||
| 1347 | qp->s_ack_state >= IB_OPCODE_RDMA_READ_REQUEST) { | ||
| 1348 | spin_unlock(&qp->s_lock); | ||
| 1349 | dev->n_rdma_dup_busy++; | ||
| 1350 | goto done; | ||
| 1351 | } | ||
| 1352 | /* RETH comes after BTH */ | ||
| 1353 | if (!header_in_data) | ||
| 1354 | reth = &ohdr->u.rc.reth; | ||
| 1355 | else { | ||
| 1356 | reth = (struct ib_reth *)data; | ||
| 1357 | data += sizeof(*reth); | ||
| 1358 | } | ||
| 1359 | qp->s_rdma_len = be32_to_cpu(reth->length); | ||
| 1360 | if (qp->s_rdma_len != 0) { | ||
| 1361 | u32 rkey = be32_to_cpu(reth->rkey); | ||
| 1362 | u64 vaddr = be64_to_cpu(reth->vaddr); | ||
| 1363 | int ok; | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * Address range must be a subset of the original | ||
| 1367 | * request and start on pmtu boundaries. | ||
| 1368 | */ | ||
| 1369 | ok = ipath_rkey_ok(dev, &qp->s_rdma_sge, | ||
| 1370 | qp->s_rdma_len, vaddr, rkey, | ||
| 1371 | IB_ACCESS_REMOTE_READ); | ||
| 1372 | if (unlikely(!ok)) | ||
| 1373 | goto done; | ||
| 1374 | } else { | ||
| 1375 | qp->s_rdma_sge.sg_list = NULL; | ||
| 1376 | qp->s_rdma_sge.num_sge = 0; | ||
| 1377 | qp->s_rdma_sge.sge.mr = NULL; | ||
| 1378 | qp->s_rdma_sge.sge.vaddr = NULL; | ||
| 1379 | qp->s_rdma_sge.sge.length = 0; | ||
| 1380 | qp->s_rdma_sge.sge.sge_length = 0; | ||
| 1381 | } | ||
| 1382 | break; | ||
| 1383 | |||
| 1384 | case OP(COMPARE_SWAP): | ||
| 1385 | case OP(FETCH_ADD): | ||
| 1386 | /* | ||
| 1387 | * Check for the PSN of the last atomic operations | ||
| 1388 | * performed and resend the result if found. | ||
| 1389 | */ | ||
| 1390 | if ((psn & IPS_PSN_MASK) != qp->r_atomic_psn) { | ||
| 1391 | spin_unlock(&qp->s_lock); | ||
| 1392 | goto done; | ||
| 1393 | } | ||
| 1394 | qp->s_ack_atomic = qp->r_atomic_data; | ||
| 1395 | break; | ||
| 1396 | } | ||
| 1397 | qp->s_ack_state = opcode; | ||
| 1398 | qp->s_nak_state = 0; | ||
| 1399 | qp->s_ack_psn = psn; | ||
| 1400 | resched: | ||
| 1401 | return 0; | ||
| 1402 | |||
| 1403 | done: | ||
| 1404 | return 1; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | /** | ||
| 1408 | * ipath_rc_rcv - process an incoming RC packet | ||
| 1409 | * @dev: the device this packet came in on | ||
| 1410 | * @hdr: the header of this packet | ||
| 1411 | * @has_grh: true if the header has a GRH | ||
| 1412 | * @data: the packet data | ||
| 1413 | * @tlen: the packet length | ||
| 1414 | * @qp: the QP for this packet | ||
| 1415 | * | ||
| 1416 | * This is called from ipath_qp_rcv() to process an incoming RC packet | ||
| 1417 | * for the given QP. | ||
| 1418 | * Called at interrupt level. | ||
| 1419 | */ | ||
| 1420 | void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 1421 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp) | ||
| 1422 | { | ||
| 1423 | struct ipath_other_headers *ohdr; | ||
| 1424 | u32 opcode; | ||
| 1425 | u32 hdrsize; | ||
| 1426 | u32 psn; | ||
| 1427 | u32 pad; | ||
| 1428 | unsigned long flags; | ||
| 1429 | struct ib_wc wc; | ||
| 1430 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
| 1431 | int diff; | ||
| 1432 | struct ib_reth *reth; | ||
| 1433 | int header_in_data; | ||
| 1434 | |||
| 1435 | /* Check for GRH */ | ||
| 1436 | if (!has_grh) { | ||
| 1437 | ohdr = &hdr->u.oth; | ||
| 1438 | hdrsize = 8 + 12; /* LRH + BTH */ | ||
| 1439 | psn = be32_to_cpu(ohdr->bth[2]); | ||
| 1440 | header_in_data = 0; | ||
| 1441 | } else { | ||
| 1442 | ohdr = &hdr->u.l.oth; | ||
| 1443 | hdrsize = 8 + 40 + 12; /* LRH + GRH + BTH */ | ||
| 1444 | /* | ||
| 1445 | * The header with GRH is 60 bytes and the core driver sets | ||
| 1446 | * the eager header buffer size to 56 bytes so the last 4 | ||
| 1447 | * bytes of the BTH header (PSN) is in the data buffer. | ||
| 1448 | */ | ||
| 1449 | header_in_data = | ||
| 1450 | ipath_layer_get_rcvhdrentsize(dev->dd) == 16; | ||
| 1451 | if (header_in_data) { | ||
| 1452 | psn = be32_to_cpu(((__be32 *) data)[0]); | ||
| 1453 | data += sizeof(__be32); | ||
| 1454 | } else | ||
| 1455 | psn = be32_to_cpu(ohdr->bth[2]); | ||
| 1456 | } | ||
| 1457 | /* | ||
| 1458 | * The opcode is in the low byte when its in network order | ||
| 1459 | * (top byte when in host order). | ||
| 1460 | */ | ||
| 1461 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | ||
| 1462 | |||
| 1463 | /* | ||
| 1464 | * Process responses (ACKs) before anything else. Note that the | ||
| 1465 | * packet sequence number will be for something in the send work | ||
| 1466 | * queue rather than the expected receive packet sequence number. | ||
| 1467 | * In other words, this QP is the requester. | ||
| 1468 | */ | ||
| 1469 | if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) && | ||
| 1470 | opcode <= OP(ATOMIC_ACKNOWLEDGE)) { | ||
| 1471 | ipath_rc_rcv_resp(dev, ohdr, data, tlen, qp, opcode, psn, | ||
| 1472 | hdrsize, pmtu, header_in_data); | ||
| 1473 | goto bail; | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 1477 | |||
| 1478 | /* Compute 24 bits worth of difference. */ | ||
| 1479 | diff = ipath_cmp24(psn, qp->r_psn); | ||
| 1480 | if (unlikely(diff)) { | ||
| 1481 | if (ipath_rc_rcv_error(dev, ohdr, data, qp, opcode, | ||
| 1482 | psn, diff, header_in_data)) | ||
| 1483 | goto done; | ||
| 1484 | goto resched; | ||
| 1485 | } | ||
| 1486 | |||
| 1487 | /* Check for opcode sequence errors. */ | ||
| 1488 | switch (qp->r_state) { | ||
| 1489 | case OP(SEND_FIRST): | ||
| 1490 | case OP(SEND_MIDDLE): | ||
| 1491 | if (opcode == OP(SEND_MIDDLE) || | ||
| 1492 | opcode == OP(SEND_LAST) || | ||
| 1493 | opcode == OP(SEND_LAST_WITH_IMMEDIATE)) | ||
| 1494 | break; | ||
| 1495 | nack_inv: | ||
| 1496 | /* | ||
| 1497 | * A NAK will ACK earlier sends and RDMA writes. Don't queue the | ||
| 1498 | * NAK if a RDMA read, atomic, or NAK is pending though. | ||
| 1499 | */ | ||
| 1500 | spin_lock(&qp->s_lock); | ||
| 1501 | if (qp->s_ack_state >= OP(RDMA_READ_REQUEST) && | ||
| 1502 | qp->s_ack_state != IB_OPCODE_ACKNOWLEDGE) { | ||
| 1503 | spin_unlock(&qp->s_lock); | ||
| 1504 | goto done; | ||
| 1505 | } | ||
| 1506 | /* XXX Flush WQEs */ | ||
| 1507 | qp->state = IB_QPS_ERR; | ||
| 1508 | qp->s_ack_state = OP(SEND_ONLY); | ||
| 1509 | qp->s_nak_state = IB_NAK_INVALID_REQUEST; | ||
| 1510 | qp->s_ack_psn = qp->r_psn; | ||
| 1511 | goto resched; | ||
| 1512 | |||
| 1513 | case OP(RDMA_WRITE_FIRST): | ||
| 1514 | case OP(RDMA_WRITE_MIDDLE): | ||
| 1515 | if (opcode == OP(RDMA_WRITE_MIDDLE) || | ||
| 1516 | opcode == OP(RDMA_WRITE_LAST) || | ||
| 1517 | opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) | ||
| 1518 | break; | ||
| 1519 | goto nack_inv; | ||
| 1520 | |||
| 1521 | case OP(RDMA_READ_REQUEST): | ||
| 1522 | case OP(COMPARE_SWAP): | ||
| 1523 | case OP(FETCH_ADD): | ||
| 1524 | /* | ||
| 1525 | * Drop all new requests until a response has been sent. A | ||
| 1526 | * new request then ACKs the RDMA response we sent. Relaxed | ||
| 1527 | * ordering would allow new requests to be processed but we | ||
| 1528 | * would need to keep a queue of rwqe's for all that are in | ||
| 1529 | * progress. Note that we can't RNR NAK this request since | ||
| 1530 | * the RDMA READ or atomic response is already queued to be | ||
| 1531 | * sent (unless we implement a response send queue). | ||
| 1532 | */ | ||
| 1533 | goto done; | ||
| 1534 | |||
| 1535 | default: | ||
| 1536 | if (opcode == OP(SEND_MIDDLE) || | ||
| 1537 | opcode == OP(SEND_LAST) || | ||
| 1538 | opcode == OP(SEND_LAST_WITH_IMMEDIATE) || | ||
| 1539 | opcode == OP(RDMA_WRITE_MIDDLE) || | ||
| 1540 | opcode == OP(RDMA_WRITE_LAST) || | ||
| 1541 | opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) | ||
| 1542 | goto nack_inv; | ||
| 1543 | break; | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | wc.imm_data = 0; | ||
| 1547 | wc.wc_flags = 0; | ||
| 1548 | |||
| 1549 | /* OK, process the packet. */ | ||
| 1550 | switch (opcode) { | ||
| 1551 | case OP(SEND_FIRST): | ||
| 1552 | if (!ipath_get_rwqe(qp, 0)) { | ||
| 1553 | rnr_nak: | ||
| 1554 | /* | ||
| 1555 | * A RNR NAK will ACK earlier sends and RDMA writes. | ||
| 1556 | * Don't queue the NAK if a RDMA read or atomic | ||
| 1557 | * is pending though. | ||
| 1558 | */ | ||
| 1559 | spin_lock(&qp->s_lock); | ||
| 1560 | if (qp->s_ack_state >= | ||
| 1561 | OP(RDMA_READ_REQUEST) && | ||
| 1562 | qp->s_ack_state != IB_OPCODE_ACKNOWLEDGE) { | ||
| 1563 | spin_unlock(&qp->s_lock); | ||
| 1564 | goto done; | ||
| 1565 | } | ||
| 1566 | qp->s_ack_state = OP(SEND_ONLY); | ||
| 1567 | qp->s_nak_state = IB_RNR_NAK | qp->s_min_rnr_timer; | ||
| 1568 | qp->s_ack_psn = qp->r_psn; | ||
| 1569 | goto resched; | ||
| 1570 | } | ||
| 1571 | qp->r_rcv_len = 0; | ||
| 1572 | /* FALLTHROUGH */ | ||
| 1573 | case OP(SEND_MIDDLE): | ||
| 1574 | case OP(RDMA_WRITE_MIDDLE): | ||
| 1575 | send_middle: | ||
| 1576 | /* Check for invalid length PMTU or posted rwqe len. */ | ||
| 1577 | if (unlikely(tlen != (hdrsize + pmtu + 4))) | ||
| 1578 | goto nack_inv; | ||
| 1579 | qp->r_rcv_len += pmtu; | ||
| 1580 | if (unlikely(qp->r_rcv_len > qp->r_len)) | ||
| 1581 | goto nack_inv; | ||
| 1582 | ipath_copy_sge(&qp->r_sge, data, pmtu); | ||
| 1583 | break; | ||
| 1584 | |||
| 1585 | case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): | ||
| 1586 | /* consume RWQE */ | ||
| 1587 | if (!ipath_get_rwqe(qp, 1)) | ||
| 1588 | goto rnr_nak; | ||
| 1589 | goto send_last_imm; | ||
| 1590 | |||
| 1591 | case OP(SEND_ONLY): | ||
| 1592 | case OP(SEND_ONLY_WITH_IMMEDIATE): | ||
| 1593 | if (!ipath_get_rwqe(qp, 0)) | ||
| 1594 | goto rnr_nak; | ||
| 1595 | qp->r_rcv_len = 0; | ||
| 1596 | if (opcode == OP(SEND_ONLY)) | ||
| 1597 | goto send_last; | ||
| 1598 | /* FALLTHROUGH */ | ||
| 1599 | case OP(SEND_LAST_WITH_IMMEDIATE): | ||
| 1600 | send_last_imm: | ||
| 1601 | if (header_in_data) { | ||
| 1602 | wc.imm_data = *(__be32 *) data; | ||
| 1603 | data += sizeof(__be32); | ||
| 1604 | } else { | ||
| 1605 | /* Immediate data comes after BTH */ | ||
| 1606 | wc.imm_data = ohdr->u.imm_data; | ||
| 1607 | } | ||
| 1608 | hdrsize += 4; | ||
| 1609 | wc.wc_flags = IB_WC_WITH_IMM; | ||
| 1610 | /* FALLTHROUGH */ | ||
| 1611 | case OP(SEND_LAST): | ||
| 1612 | case OP(RDMA_WRITE_LAST): | ||
| 1613 | send_last: | ||
| 1614 | /* Get the number of bytes the message was padded by. */ | ||
| 1615 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 1616 | /* Check for invalid length. */ | ||
| 1617 | /* XXX LAST len should be >= 1 */ | ||
| 1618 | if (unlikely(tlen < (hdrsize + pad + 4))) | ||
| 1619 | goto nack_inv; | ||
| 1620 | /* Don't count the CRC. */ | ||
| 1621 | tlen -= (hdrsize + pad + 4); | ||
| 1622 | wc.byte_len = tlen + qp->r_rcv_len; | ||
| 1623 | if (unlikely(wc.byte_len > qp->r_len)) | ||
| 1624 | goto nack_inv; | ||
| 1625 | ipath_copy_sge(&qp->r_sge, data, tlen); | ||
| 1626 | atomic_inc(&qp->msn); | ||
| 1627 | if (opcode == OP(RDMA_WRITE_LAST) || | ||
| 1628 | opcode == OP(RDMA_WRITE_ONLY)) | ||
| 1629 | break; | ||
| 1630 | wc.wr_id = qp->r_wr_id; | ||
| 1631 | wc.status = IB_WC_SUCCESS; | ||
| 1632 | wc.opcode = IB_WC_RECV; | ||
| 1633 | wc.vendor_err = 0; | ||
| 1634 | wc.qp_num = qp->ibqp.qp_num; | ||
| 1635 | wc.src_qp = qp->remote_qpn; | ||
| 1636 | wc.pkey_index = 0; | ||
| 1637 | wc.slid = qp->remote_ah_attr.dlid; | ||
| 1638 | wc.sl = qp->remote_ah_attr.sl; | ||
| 1639 | wc.dlid_path_bits = 0; | ||
| 1640 | wc.port_num = 0; | ||
| 1641 | /* Signal completion event if the solicited bit is set. */ | ||
| 1642 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | ||
| 1643 | (ohdr->bth[0] & | ||
| 1644 | __constant_cpu_to_be32(1 << 23)) != 0); | ||
| 1645 | break; | ||
| 1646 | |||
| 1647 | case OP(RDMA_WRITE_FIRST): | ||
| 1648 | case OP(RDMA_WRITE_ONLY): | ||
| 1649 | case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): | ||
| 1650 | /* consume RWQE */ | ||
| 1651 | /* RETH comes after BTH */ | ||
| 1652 | if (!header_in_data) | ||
| 1653 | reth = &ohdr->u.rc.reth; | ||
| 1654 | else { | ||
| 1655 | reth = (struct ib_reth *)data; | ||
| 1656 | data += sizeof(*reth); | ||
| 1657 | } | ||
| 1658 | hdrsize += sizeof(*reth); | ||
| 1659 | qp->r_len = be32_to_cpu(reth->length); | ||
| 1660 | qp->r_rcv_len = 0; | ||
| 1661 | if (qp->r_len != 0) { | ||
| 1662 | u32 rkey = be32_to_cpu(reth->rkey); | ||
| 1663 | u64 vaddr = be64_to_cpu(reth->vaddr); | ||
| 1664 | int ok; | ||
| 1665 | |||
| 1666 | /* Check rkey & NAK */ | ||
| 1667 | ok = ipath_rkey_ok(dev, &qp->r_sge, | ||
| 1668 | qp->r_len, vaddr, rkey, | ||
| 1669 | IB_ACCESS_REMOTE_WRITE); | ||
| 1670 | if (unlikely(!ok)) { | ||
| 1671 | nack_acc: | ||
| 1672 | /* | ||
| 1673 | * A NAK will ACK earlier sends and RDMA | ||
| 1674 | * writes. Don't queue the NAK if a RDMA | ||
| 1675 | * read, atomic, or NAK is pending though. | ||
| 1676 | */ | ||
| 1677 | spin_lock(&qp->s_lock); | ||
| 1678 | if (qp->s_ack_state >= | ||
| 1679 | OP(RDMA_READ_REQUEST) && | ||
| 1680 | qp->s_ack_state != | ||
| 1681 | IB_OPCODE_ACKNOWLEDGE) { | ||
| 1682 | spin_unlock(&qp->s_lock); | ||
| 1683 | goto done; | ||
| 1684 | } | ||
| 1685 | /* XXX Flush WQEs */ | ||
| 1686 | qp->state = IB_QPS_ERR; | ||
| 1687 | qp->s_ack_state = OP(RDMA_WRITE_ONLY); | ||
| 1688 | qp->s_nak_state = | ||
| 1689 | IB_NAK_REMOTE_ACCESS_ERROR; | ||
| 1690 | qp->s_ack_psn = qp->r_psn; | ||
| 1691 | goto resched; | ||
| 1692 | } | ||
| 1693 | } else { | ||
| 1694 | qp->r_sge.sg_list = NULL; | ||
| 1695 | qp->r_sge.sge.mr = NULL; | ||
| 1696 | qp->r_sge.sge.vaddr = NULL; | ||
| 1697 | qp->r_sge.sge.length = 0; | ||
| 1698 | qp->r_sge.sge.sge_length = 0; | ||
| 1699 | } | ||
| 1700 | if (unlikely(!(qp->qp_access_flags & | ||
| 1701 | IB_ACCESS_REMOTE_WRITE))) | ||
| 1702 | goto nack_acc; | ||
| 1703 | if (opcode == OP(RDMA_WRITE_FIRST)) | ||
| 1704 | goto send_middle; | ||
| 1705 | else if (opcode == OP(RDMA_WRITE_ONLY)) | ||
| 1706 | goto send_last; | ||
| 1707 | if (!ipath_get_rwqe(qp, 1)) | ||
| 1708 | goto rnr_nak; | ||
| 1709 | goto send_last_imm; | ||
| 1710 | |||
| 1711 | case OP(RDMA_READ_REQUEST): | ||
| 1712 | /* RETH comes after BTH */ | ||
| 1713 | if (!header_in_data) | ||
| 1714 | reth = &ohdr->u.rc.reth; | ||
| 1715 | else { | ||
| 1716 | reth = (struct ib_reth *)data; | ||
| 1717 | data += sizeof(*reth); | ||
| 1718 | } | ||
| 1719 | spin_lock(&qp->s_lock); | ||
| 1720 | if (qp->s_ack_state != OP(ACKNOWLEDGE) && | ||
| 1721 | qp->s_ack_state >= IB_OPCODE_RDMA_READ_REQUEST) { | ||
| 1722 | spin_unlock(&qp->s_lock); | ||
| 1723 | goto done; | ||
| 1724 | } | ||
| 1725 | qp->s_rdma_len = be32_to_cpu(reth->length); | ||
| 1726 | if (qp->s_rdma_len != 0) { | ||
| 1727 | u32 rkey = be32_to_cpu(reth->rkey); | ||
| 1728 | u64 vaddr = be64_to_cpu(reth->vaddr); | ||
| 1729 | int ok; | ||
| 1730 | |||
| 1731 | /* Check rkey & NAK */ | ||
| 1732 | ok = ipath_rkey_ok(dev, &qp->s_rdma_sge, | ||
| 1733 | qp->s_rdma_len, vaddr, rkey, | ||
| 1734 | IB_ACCESS_REMOTE_READ); | ||
| 1735 | if (unlikely(!ok)) { | ||
| 1736 | spin_unlock(&qp->s_lock); | ||
| 1737 | goto nack_acc; | ||
| 1738 | } | ||
| 1739 | /* | ||
| 1740 | * Update the next expected PSN. We add 1 later | ||
| 1741 | * below, so only add the remainder here. | ||
| 1742 | */ | ||
| 1743 | if (qp->s_rdma_len > pmtu) | ||
| 1744 | qp->r_psn += (qp->s_rdma_len - 1) / pmtu; | ||
| 1745 | } else { | ||
| 1746 | qp->s_rdma_sge.sg_list = NULL; | ||
| 1747 | qp->s_rdma_sge.num_sge = 0; | ||
| 1748 | qp->s_rdma_sge.sge.mr = NULL; | ||
| 1749 | qp->s_rdma_sge.sge.vaddr = NULL; | ||
| 1750 | qp->s_rdma_sge.sge.length = 0; | ||
| 1751 | qp->s_rdma_sge.sge.sge_length = 0; | ||
| 1752 | } | ||
| 1753 | if (unlikely(!(qp->qp_access_flags & | ||
| 1754 | IB_ACCESS_REMOTE_READ))) | ||
| 1755 | goto nack_acc; | ||
| 1756 | /* | ||
| 1757 | * We need to increment the MSN here instead of when we | ||
| 1758 | * finish sending the result since a duplicate request would | ||
| 1759 | * increment it more than once. | ||
| 1760 | */ | ||
| 1761 | atomic_inc(&qp->msn); | ||
| 1762 | qp->s_ack_state = opcode; | ||
| 1763 | qp->s_nak_state = 0; | ||
| 1764 | qp->s_ack_psn = psn; | ||
| 1765 | qp->r_psn++; | ||
| 1766 | qp->r_state = opcode; | ||
| 1767 | goto rdmadone; | ||
| 1768 | |||
| 1769 | case OP(COMPARE_SWAP): | ||
| 1770 | case OP(FETCH_ADD): { | ||
| 1771 | struct ib_atomic_eth *ateth; | ||
| 1772 | u64 vaddr; | ||
| 1773 | u64 sdata; | ||
| 1774 | u32 rkey; | ||
| 1775 | |||
| 1776 | if (!header_in_data) | ||
| 1777 | ateth = &ohdr->u.atomic_eth; | ||
| 1778 | else { | ||
| 1779 | ateth = (struct ib_atomic_eth *)data; | ||
| 1780 | data += sizeof(*ateth); | ||
| 1781 | } | ||
| 1782 | vaddr = be64_to_cpu(ateth->vaddr); | ||
| 1783 | if (unlikely(vaddr & (sizeof(u64) - 1))) | ||
| 1784 | goto nack_inv; | ||
| 1785 | rkey = be32_to_cpu(ateth->rkey); | ||
| 1786 | /* Check rkey & NAK */ | ||
| 1787 | if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, | ||
| 1788 | sizeof(u64), vaddr, rkey, | ||
| 1789 | IB_ACCESS_REMOTE_ATOMIC))) | ||
| 1790 | goto nack_acc; | ||
| 1791 | if (unlikely(!(qp->qp_access_flags & | ||
| 1792 | IB_ACCESS_REMOTE_ATOMIC))) | ||
| 1793 | goto nack_acc; | ||
| 1794 | /* Perform atomic OP and save result. */ | ||
| 1795 | sdata = be64_to_cpu(ateth->swap_data); | ||
| 1796 | spin_lock(&dev->pending_lock); | ||
| 1797 | qp->r_atomic_data = *(u64 *) qp->r_sge.sge.vaddr; | ||
| 1798 | if (opcode == OP(FETCH_ADD)) | ||
| 1799 | *(u64 *) qp->r_sge.sge.vaddr = | ||
| 1800 | qp->r_atomic_data + sdata; | ||
| 1801 | else if (qp->r_atomic_data == | ||
| 1802 | be64_to_cpu(ateth->compare_data)) | ||
| 1803 | *(u64 *) qp->r_sge.sge.vaddr = sdata; | ||
| 1804 | spin_unlock(&dev->pending_lock); | ||
| 1805 | atomic_inc(&qp->msn); | ||
| 1806 | qp->r_atomic_psn = psn & IPS_PSN_MASK; | ||
| 1807 | psn |= 1 << 31; | ||
| 1808 | break; | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | default: | ||
| 1812 | /* Drop packet for unknown opcodes. */ | ||
| 1813 | goto done; | ||
| 1814 | } | ||
| 1815 | qp->r_psn++; | ||
| 1816 | qp->r_state = opcode; | ||
| 1817 | /* Send an ACK if requested or required. */ | ||
| 1818 | if (psn & (1 << 31)) { | ||
| 1819 | /* | ||
| 1820 | * Coalesce ACKs unless there is a RDMA READ or | ||
| 1821 | * ATOMIC pending. | ||
| 1822 | */ | ||
| 1823 | spin_lock(&qp->s_lock); | ||
| 1824 | if (qp->s_ack_state == OP(ACKNOWLEDGE) || | ||
| 1825 | qp->s_ack_state < IB_OPCODE_RDMA_READ_REQUEST) { | ||
| 1826 | qp->s_ack_state = opcode; | ||
| 1827 | qp->s_nak_state = 0; | ||
| 1828 | qp->s_ack_psn = psn; | ||
| 1829 | qp->s_ack_atomic = qp->r_atomic_data; | ||
| 1830 | goto resched; | ||
| 1831 | } | ||
| 1832 | spin_unlock(&qp->s_lock); | ||
| 1833 | } | ||
| 1834 | done: | ||
| 1835 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 1836 | goto bail; | ||
| 1837 | |||
| 1838 | resched: | ||
| 1839 | /* | ||
| 1840 | * Try to send ACK right away but not if ipath_do_rc_send() is | ||
| 1841 | * active. | ||
| 1842 | */ | ||
| 1843 | if (qp->s_hdrwords == 0 && | ||
| 1844 | (qp->s_ack_state < IB_OPCODE_RDMA_READ_REQUEST || | ||
| 1845 | qp->s_ack_state >= IB_OPCODE_COMPARE_SWAP)) | ||
| 1846 | send_rc_ack(qp); | ||
| 1847 | |||
| 1848 | rdmadone: | ||
| 1849 | spin_unlock(&qp->s_lock); | ||
| 1850 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 1851 | |||
| 1852 | /* Call ipath_do_rc_send() in another thread. */ | ||
| 1853 | tasklet_hi_schedule(&qp->s_task); | ||
| 1854 | |||
| 1855 | bail: | ||
| 1856 | return; | ||
| 1857 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h new file mode 100644 index 000000000000..1e59750c5f63 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_registers.h | |||
| @@ -0,0 +1,446 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _IPATH_REGISTERS_H | ||
| 34 | #define _IPATH_REGISTERS_H | ||
| 35 | |||
| 36 | /* | ||
| 37 | * This file should only be included by kernel source, and by the diags. | ||
| 38 | * It defines the registers, and their contents, for the InfiniPath HT-400 chip | ||
| 39 | */ | ||
| 40 | |||
| 41 | /* | ||
| 42 | * These are the InfiniPath register and buffer bit definitions, | ||
| 43 | * that are visible to software, and needed only by the kernel | ||
| 44 | * and diag code. A few, that are visible to protocol and user | ||
| 45 | * code are in ipath_common.h. Some bits are specific | ||
| 46 | * to a given chip implementation, and have been moved to the | ||
| 47 | * chip-specific source file | ||
| 48 | */ | ||
| 49 | |||
| 50 | /* kr_revision bits */ | ||
| 51 | #define INFINIPATH_R_CHIPREVMINOR_MASK 0xFF | ||
| 52 | #define INFINIPATH_R_CHIPREVMINOR_SHIFT 0 | ||
| 53 | #define INFINIPATH_R_CHIPREVMAJOR_MASK 0xFF | ||
| 54 | #define INFINIPATH_R_CHIPREVMAJOR_SHIFT 8 | ||
| 55 | #define INFINIPATH_R_ARCH_MASK 0xFF | ||
| 56 | #define INFINIPATH_R_ARCH_SHIFT 16 | ||
| 57 | #define INFINIPATH_R_SOFTWARE_MASK 0xFF | ||
| 58 | #define INFINIPATH_R_SOFTWARE_SHIFT 24 | ||
| 59 | #define INFINIPATH_R_BOARDID_MASK 0xFF | ||
| 60 | #define INFINIPATH_R_BOARDID_SHIFT 32 | ||
| 61 | |||
| 62 | /* kr_control bits */ | ||
| 63 | #define INFINIPATH_C_FREEZEMODE 0x00000002 | ||
| 64 | #define INFINIPATH_C_LINKENABLE 0x00000004 | ||
| 65 | #define INFINIPATH_C_RESET 0x00000001 | ||
| 66 | |||
| 67 | /* kr_sendctrl bits */ | ||
| 68 | #define INFINIPATH_S_DISARMPIOBUF_SHIFT 16 | ||
| 69 | |||
| 70 | #define IPATH_S_ABORT 0 | ||
| 71 | #define IPATH_S_PIOINTBUFAVAIL 1 | ||
| 72 | #define IPATH_S_PIOBUFAVAILUPD 2 | ||
| 73 | #define IPATH_S_PIOENABLE 3 | ||
| 74 | #define IPATH_S_DISARM 31 | ||
| 75 | |||
| 76 | #define INFINIPATH_S_ABORT (1U << IPATH_S_ABORT) | ||
| 77 | #define INFINIPATH_S_PIOINTBUFAVAIL (1U << IPATH_S_PIOINTBUFAVAIL) | ||
| 78 | #define INFINIPATH_S_PIOBUFAVAILUPD (1U << IPATH_S_PIOBUFAVAILUPD) | ||
| 79 | #define INFINIPATH_S_PIOENABLE (1U << IPATH_S_PIOENABLE) | ||
| 80 | #define INFINIPATH_S_DISARM (1U << IPATH_S_DISARM) | ||
| 81 | |||
| 82 | /* kr_rcvctrl bits */ | ||
| 83 | #define INFINIPATH_R_PORTENABLE_SHIFT 0 | ||
| 84 | #define INFINIPATH_R_INTRAVAIL_SHIFT 16 | ||
| 85 | #define INFINIPATH_R_TAILUPD 0x80000000 | ||
| 86 | |||
| 87 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | ||
| 88 | #define INFINIPATH_I_RCVURG_SHIFT 0 | ||
| 89 | #define INFINIPATH_I_RCVAVAIL_SHIFT 12 | ||
| 90 | #define INFINIPATH_I_ERROR 0x80000000 | ||
| 91 | #define INFINIPATH_I_SPIOSENT 0x40000000 | ||
| 92 | #define INFINIPATH_I_SPIOBUFAVAIL 0x20000000 | ||
| 93 | #define INFINIPATH_I_GPIO 0x10000000 | ||
| 94 | |||
| 95 | /* kr_errorstatus, kr_errorclear, kr_errormask bits */ | ||
| 96 | #define INFINIPATH_E_RFORMATERR 0x0000000000000001ULL | ||
| 97 | #define INFINIPATH_E_RVCRC 0x0000000000000002ULL | ||
| 98 | #define INFINIPATH_E_RICRC 0x0000000000000004ULL | ||
| 99 | #define INFINIPATH_E_RMINPKTLEN 0x0000000000000008ULL | ||
| 100 | #define INFINIPATH_E_RMAXPKTLEN 0x0000000000000010ULL | ||
| 101 | #define INFINIPATH_E_RLONGPKTLEN 0x0000000000000020ULL | ||
| 102 | #define INFINIPATH_E_RSHORTPKTLEN 0x0000000000000040ULL | ||
| 103 | #define INFINIPATH_E_RUNEXPCHAR 0x0000000000000080ULL | ||
| 104 | #define INFINIPATH_E_RUNSUPVL 0x0000000000000100ULL | ||
| 105 | #define INFINIPATH_E_REBP 0x0000000000000200ULL | ||
| 106 | #define INFINIPATH_E_RIBFLOW 0x0000000000000400ULL | ||
| 107 | #define INFINIPATH_E_RBADVERSION 0x0000000000000800ULL | ||
| 108 | #define INFINIPATH_E_RRCVEGRFULL 0x0000000000001000ULL | ||
| 109 | #define INFINIPATH_E_RRCVHDRFULL 0x0000000000002000ULL | ||
| 110 | #define INFINIPATH_E_RBADTID 0x0000000000004000ULL | ||
| 111 | #define INFINIPATH_E_RHDRLEN 0x0000000000008000ULL | ||
| 112 | #define INFINIPATH_E_RHDR 0x0000000000010000ULL | ||
| 113 | #define INFINIPATH_E_RIBLOSTLINK 0x0000000000020000ULL | ||
| 114 | #define INFINIPATH_E_SMINPKTLEN 0x0000000020000000ULL | ||
| 115 | #define INFINIPATH_E_SMAXPKTLEN 0x0000000040000000ULL | ||
| 116 | #define INFINIPATH_E_SUNDERRUN 0x0000000080000000ULL | ||
| 117 | #define INFINIPATH_E_SPKTLEN 0x0000000100000000ULL | ||
| 118 | #define INFINIPATH_E_SDROPPEDSMPPKT 0x0000000200000000ULL | ||
| 119 | #define INFINIPATH_E_SDROPPEDDATAPKT 0x0000000400000000ULL | ||
| 120 | #define INFINIPATH_E_SPIOARMLAUNCH 0x0000000800000000ULL | ||
| 121 | #define INFINIPATH_E_SUNEXPERRPKTNUM 0x0000001000000000ULL | ||
| 122 | #define INFINIPATH_E_SUNSUPVL 0x0000002000000000ULL | ||
| 123 | #define INFINIPATH_E_IBSTATUSCHANGED 0x0001000000000000ULL | ||
| 124 | #define INFINIPATH_E_INVALIDADDR 0x0002000000000000ULL | ||
| 125 | #define INFINIPATH_E_RESET 0x0004000000000000ULL | ||
| 126 | #define INFINIPATH_E_HARDWARE 0x0008000000000000ULL | ||
| 127 | |||
| 128 | /* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ | ||
| 129 | /* TXEMEMPARITYERR bit 0: PIObuf, 1: PIOpbc, 2: launchfifo | ||
| 130 | * RXEMEMPARITYERR bit 0: rcvbuf, 1: lookupq, 2: eagerTID, 3: expTID | ||
| 131 | * bit 4: flag buffer, 5: datainfo, 6: header info */ | ||
| 132 | #define INFINIPATH_HWE_TXEMEMPARITYERR_MASK 0xFULL | ||
| 133 | #define INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT 40 | ||
| 134 | #define INFINIPATH_HWE_RXEMEMPARITYERR_MASK 0x7FULL | ||
| 135 | #define INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT 44 | ||
| 136 | #define INFINIPATH_HWE_RXDSYNCMEMPARITYERR 0x0000000400000000ULL | ||
| 137 | #define INFINIPATH_HWE_MEMBISTFAILED 0x0040000000000000ULL | ||
| 138 | #define INFINIPATH_HWE_IBCBUSTOSPCPARITYERR 0x4000000000000000ULL | ||
| 139 | #define INFINIPATH_HWE_IBCBUSFRSPCPARITYERR 0x8000000000000000ULL | ||
| 140 | |||
| 141 | /* kr_hwdiagctrl bits */ | ||
| 142 | #define INFINIPATH_DC_FORCETXEMEMPARITYERR_MASK 0xFULL | ||
| 143 | #define INFINIPATH_DC_FORCETXEMEMPARITYERR_SHIFT 40 | ||
| 144 | #define INFINIPATH_DC_FORCERXEMEMPARITYERR_MASK 0x7FULL | ||
| 145 | #define INFINIPATH_DC_FORCERXEMEMPARITYERR_SHIFT 44 | ||
| 146 | #define INFINIPATH_DC_FORCERXDSYNCMEMPARITYERR 0x0000000400000000ULL | ||
| 147 | #define INFINIPATH_DC_COUNTERDISABLE 0x1000000000000000ULL | ||
| 148 | #define INFINIPATH_DC_COUNTERWREN 0x2000000000000000ULL | ||
| 149 | #define INFINIPATH_DC_FORCEIBCBUSTOSPCPARITYERR 0x4000000000000000ULL | ||
| 150 | #define INFINIPATH_DC_FORCEIBCBUSFRSPCPARITYERR 0x8000000000000000ULL | ||
| 151 | |||
| 152 | /* kr_ibcctrl bits */ | ||
| 153 | #define INFINIPATH_IBCC_FLOWCTRLPERIOD_MASK 0xFFULL | ||
| 154 | #define INFINIPATH_IBCC_FLOWCTRLPERIOD_SHIFT 0 | ||
| 155 | #define INFINIPATH_IBCC_FLOWCTRLWATERMARK_MASK 0xFFULL | ||
| 156 | #define INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT 8 | ||
| 157 | #define INFINIPATH_IBCC_LINKINITCMD_MASK 0x3ULL | ||
| 158 | #define INFINIPATH_IBCC_LINKINITCMD_DISABLE 1 | ||
| 159 | #define INFINIPATH_IBCC_LINKINITCMD_POLL 2 /* cycle through TS1/TS2 till OK */ | ||
| 160 | #define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 /* wait for TS1, then go on */ | ||
| 161 | #define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16 | ||
| 162 | #define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL | ||
| 163 | #define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */ | ||
| 164 | #define INFINIPATH_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ | ||
| 165 | #define INFINIPATH_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ | ||
| 166 | #define INFINIPATH_IBCC_LINKCMD_SHIFT 18 | ||
| 167 | #define INFINIPATH_IBCC_MAXPKTLEN_MASK 0x7FFULL | ||
| 168 | #define INFINIPATH_IBCC_MAXPKTLEN_SHIFT 20 | ||
| 169 | #define INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK 0xFULL | ||
| 170 | #define INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT 32 | ||
| 171 | #define INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK 0xFULL | ||
| 172 | #define INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT 36 | ||
| 173 | #define INFINIPATH_IBCC_CREDITSCALE_MASK 0x7ULL | ||
| 174 | #define INFINIPATH_IBCC_CREDITSCALE_SHIFT 40 | ||
| 175 | #define INFINIPATH_IBCC_LOOPBACK 0x8000000000000000ULL | ||
| 176 | #define INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE 0x4000000000000000ULL | ||
| 177 | |||
| 178 | /* kr_ibcstatus bits */ | ||
| 179 | #define INFINIPATH_IBCS_LINKTRAININGSTATE_MASK 0xF | ||
| 180 | #define INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT 0 | ||
| 181 | #define INFINIPATH_IBCS_LINKSTATE_MASK 0x7 | ||
| 182 | #define INFINIPATH_IBCS_LINKSTATE_SHIFT 4 | ||
| 183 | #define INFINIPATH_IBCS_TXREADY 0x40000000 | ||
| 184 | #define INFINIPATH_IBCS_TXCREDITOK 0x80000000 | ||
| 185 | /* link training states (shift by INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) */ | ||
| 186 | #define INFINIPATH_IBCS_LT_STATE_DISABLED 0x00 | ||
| 187 | #define INFINIPATH_IBCS_LT_STATE_LINKUP 0x01 | ||
| 188 | #define INFINIPATH_IBCS_LT_STATE_POLLACTIVE 0x02 | ||
| 189 | #define INFINIPATH_IBCS_LT_STATE_POLLQUIET 0x03 | ||
| 190 | #define INFINIPATH_IBCS_LT_STATE_SLEEPDELAY 0x04 | ||
| 191 | #define INFINIPATH_IBCS_LT_STATE_SLEEPQUIET 0x05 | ||
| 192 | #define INFINIPATH_IBCS_LT_STATE_CFGDEBOUNCE 0x08 | ||
| 193 | #define INFINIPATH_IBCS_LT_STATE_CFGRCVFCFG 0x09 | ||
| 194 | #define INFINIPATH_IBCS_LT_STATE_CFGWAITRMT 0x0a | ||
| 195 | #define INFINIPATH_IBCS_LT_STATE_CFGIDLE 0x0b | ||
| 196 | #define INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN 0x0c | ||
| 197 | #define INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT 0x0e | ||
| 198 | #define INFINIPATH_IBCS_LT_STATE_RECOVERIDLE 0x0f | ||
| 199 | /* link state machine states (shift by INFINIPATH_IBCS_LINKSTATE_SHIFT) */ | ||
| 200 | #define INFINIPATH_IBCS_L_STATE_DOWN 0x0 | ||
| 201 | #define INFINIPATH_IBCS_L_STATE_INIT 0x1 | ||
| 202 | #define INFINIPATH_IBCS_L_STATE_ARM 0x2 | ||
| 203 | #define INFINIPATH_IBCS_L_STATE_ACTIVE 0x3 | ||
| 204 | #define INFINIPATH_IBCS_L_STATE_ACT_DEFER 0x4 | ||
| 205 | |||
| 206 | /* combination link status states that we use with some frequency */ | ||
| 207 | #define IPATH_IBSTATE_MASK ((INFINIPATH_IBCS_LINKTRAININGSTATE_MASK \ | ||
| 208 | << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \ | ||
| 209 | (INFINIPATH_IBCS_LINKSTATE_MASK \ | ||
| 210 | <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT)) | ||
| 211 | #define IPATH_IBSTATE_INIT ((INFINIPATH_IBCS_L_STATE_INIT \ | ||
| 212 | << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \ | ||
| 213 | (INFINIPATH_IBCS_LT_STATE_LINKUP \ | ||
| 214 | <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT)) | ||
| 215 | #define IPATH_IBSTATE_ARM ((INFINIPATH_IBCS_L_STATE_ARM \ | ||
| 216 | << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \ | ||
| 217 | (INFINIPATH_IBCS_LT_STATE_LINKUP \ | ||
| 218 | <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT)) | ||
| 219 | #define IPATH_IBSTATE_ACTIVE ((INFINIPATH_IBCS_L_STATE_ACTIVE \ | ||
| 220 | << INFINIPATH_IBCS_LINKSTATE_SHIFT) | \ | ||
| 221 | (INFINIPATH_IBCS_LT_STATE_LINKUP \ | ||
| 222 | <<INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT)) | ||
| 223 | |||
| 224 | /* kr_extstatus bits */ | ||
| 225 | #define INFINIPATH_EXTS_SERDESPLLLOCK 0x1 | ||
| 226 | #define INFINIPATH_EXTS_GPIOIN_MASK 0xFFFFULL | ||
| 227 | #define INFINIPATH_EXTS_GPIOIN_SHIFT 48 | ||
| 228 | |||
| 229 | /* kr_extctrl bits */ | ||
| 230 | #define INFINIPATH_EXTC_GPIOINVERT_MASK 0xFFFFULL | ||
| 231 | #define INFINIPATH_EXTC_GPIOINVERT_SHIFT 32 | ||
| 232 | #define INFINIPATH_EXTC_GPIOOE_MASK 0xFFFFULL | ||
| 233 | #define INFINIPATH_EXTC_GPIOOE_SHIFT 48 | ||
| 234 | #define INFINIPATH_EXTC_SERDESENABLE 0x80000000ULL | ||
| 235 | #define INFINIPATH_EXTC_SERDESCONNECT 0x40000000ULL | ||
| 236 | #define INFINIPATH_EXTC_SERDESENTRUNKING 0x20000000ULL | ||
| 237 | #define INFINIPATH_EXTC_SERDESDISRXFIFO 0x10000000ULL | ||
| 238 | #define INFINIPATH_EXTC_SERDESENPLPBK1 0x08000000ULL | ||
| 239 | #define INFINIPATH_EXTC_SERDESENPLPBK2 0x04000000ULL | ||
| 240 | #define INFINIPATH_EXTC_SERDESENENCDEC 0x02000000ULL | ||
| 241 | #define INFINIPATH_EXTC_LED1SECPORT_ON 0x00000020ULL | ||
| 242 | #define INFINIPATH_EXTC_LED2SECPORT_ON 0x00000010ULL | ||
| 243 | #define INFINIPATH_EXTC_LED1PRIPORT_ON 0x00000008ULL | ||
| 244 | #define INFINIPATH_EXTC_LED2PRIPORT_ON 0x00000004ULL | ||
| 245 | #define INFINIPATH_EXTC_LEDGBLOK_ON 0x00000002ULL | ||
| 246 | #define INFINIPATH_EXTC_LEDGBLERR_OFF 0x00000001ULL | ||
| 247 | |||
| 248 | /* kr_mdio bits */ | ||
| 249 | #define INFINIPATH_MDIO_CLKDIV_MASK 0x7FULL | ||
| 250 | #define INFINIPATH_MDIO_CLKDIV_SHIFT 32 | ||
| 251 | #define INFINIPATH_MDIO_COMMAND_MASK 0x7ULL | ||
| 252 | #define INFINIPATH_MDIO_COMMAND_SHIFT 26 | ||
| 253 | #define INFINIPATH_MDIO_DEVADDR_MASK 0x1FULL | ||
| 254 | #define INFINIPATH_MDIO_DEVADDR_SHIFT 21 | ||
| 255 | #define INFINIPATH_MDIO_REGADDR_MASK 0x1FULL | ||
| 256 | #define INFINIPATH_MDIO_REGADDR_SHIFT 16 | ||
| 257 | #define INFINIPATH_MDIO_DATA_MASK 0xFFFFULL | ||
| 258 | #define INFINIPATH_MDIO_DATA_SHIFT 0 | ||
| 259 | #define INFINIPATH_MDIO_CMDVALID 0x0000000040000000ULL | ||
| 260 | #define INFINIPATH_MDIO_RDDATAVALID 0x0000000080000000ULL | ||
| 261 | |||
| 262 | /* kr_partitionkey bits */ | ||
| 263 | #define INFINIPATH_PKEY_SIZE 16 | ||
| 264 | #define INFINIPATH_PKEY_MASK 0xFFFF | ||
| 265 | #define INFINIPATH_PKEY_DEFAULT_PKEY 0xFFFF | ||
| 266 | |||
| 267 | /* kr_serdesconfig0 bits */ | ||
| 268 | #define INFINIPATH_SERDC0_RESET_MASK 0xfULL /* overal reset bits */ | ||
| 269 | #define INFINIPATH_SERDC0_RESET_PLL 0x10000000ULL /* pll reset */ | ||
| 270 | #define INFINIPATH_SERDC0_TXIDLE 0xF000ULL /* tx idle enables (per lane) */ | ||
| 271 | #define INFINIPATH_SERDC0_RXDETECT_EN 0xF0000ULL /* rx detect enables (per lane) */ | ||
| 272 | #define INFINIPATH_SERDC0_L1PWR_DN 0xF0ULL /* L1 Power down; use with RXDETECT, | ||
| 273 | Otherwise not used on IB side */ | ||
| 274 | |||
| 275 | /* kr_xgxsconfig bits */ | ||
| 276 | #define INFINIPATH_XGXS_RESET 0x7ULL | ||
| 277 | #define INFINIPATH_XGXS_MDIOADDR_MASK 0xfULL | ||
| 278 | #define INFINIPATH_XGXS_MDIOADDR_SHIFT 4 | ||
| 279 | |||
| 280 | #define INFINIPATH_RT_ADDR_MASK 0xFFFFFFFFFFULL /* 40 bits valid */ | ||
| 281 | |||
| 282 | /* TID entries (memory), HT400-only */ | ||
| 283 | #define INFINIPATH_RT_VALID 0x8000000000000000ULL | ||
| 284 | #define INFINIPATH_RT_ADDR_SHIFT 0 | ||
| 285 | #define INFINIPATH_RT_BUFSIZE_MASK 0x3FFF | ||
| 286 | #define INFINIPATH_RT_BUFSIZE_SHIFT 48 | ||
| 287 | |||
| 288 | /* | ||
| 289 | * IPATH_PIO_MAXIBHDR is the max IB header size allowed for in our | ||
| 290 | * PIO send buffers. This is well beyond anything currently | ||
| 291 | * defined in the InfiniBand spec. | ||
| 292 | */ | ||
| 293 | #define IPATH_PIO_MAXIBHDR 128 | ||
| 294 | |||
| 295 | typedef u64 ipath_err_t; | ||
| 296 | |||
| 297 | /* mask of defined bits for various registers */ | ||
| 298 | extern u64 infinipath_i_bitsextant; | ||
| 299 | extern ipath_err_t infinipath_e_bitsextant, infinipath_hwe_bitsextant; | ||
| 300 | |||
| 301 | /* masks that are different in various chips, or only exist in some chips */ | ||
| 302 | extern u32 infinipath_i_rcvavail_mask, infinipath_i_rcvurg_mask; | ||
| 303 | |||
| 304 | /* | ||
| 305 | * register bits for selecting i2c direction and values, used for I2C serial | ||
| 306 | * flash | ||
| 307 | */ | ||
| 308 | extern u16 ipath_gpio_sda_num, ipath_gpio_scl_num; | ||
| 309 | extern u64 ipath_gpio_sda, ipath_gpio_scl; | ||
| 310 | |||
| 311 | /* | ||
| 312 | * These are the infinipath general register numbers (not offsets). | ||
| 313 | * The kernel registers are used directly, those beyond the kernel | ||
| 314 | * registers are calculated from one of the base registers. The use of | ||
| 315 | * an integer type doesn't allow type-checking as thorough as, say, | ||
| 316 | * an enum but allows for better hiding of chip differences. | ||
| 317 | */ | ||
| 318 | typedef const u16 ipath_kreg, /* infinipath general registers */ | ||
| 319 | ipath_creg, /* infinipath counter registers */ | ||
| 320 | ipath_sreg; /* kernel-only, infinipath send registers */ | ||
| 321 | |||
| 322 | /* | ||
| 323 | * These are the chip registers common to all infinipath chips, and | ||
| 324 | * used both by the kernel and the diagnostics or other user code. | ||
| 325 | * They are all implemented such that 64 bit accesses work. | ||
| 326 | * Some implement no more than 32 bits. Because 64 bit reads | ||
| 327 | * require 2 HT cmds on opteron, we access those with 32 bit | ||
| 328 | * reads for efficiency (they are written as 64 bits, since | ||
| 329 | * the extra 32 bits are nearly free on writes, and it slightly reduces | ||
| 330 | * complexity). The rest are all accessed as 64 bits. | ||
| 331 | */ | ||
| 332 | struct ipath_kregs { | ||
| 333 | /* These are the 32 bit group */ | ||
| 334 | ipath_kreg kr_control; | ||
| 335 | ipath_kreg kr_counterregbase; | ||
| 336 | ipath_kreg kr_intmask; | ||
| 337 | ipath_kreg kr_intstatus; | ||
| 338 | ipath_kreg kr_pagealign; | ||
| 339 | ipath_kreg kr_portcnt; | ||
| 340 | ipath_kreg kr_rcvtidbase; | ||
| 341 | ipath_kreg kr_rcvtidcnt; | ||
| 342 | ipath_kreg kr_rcvegrbase; | ||
| 343 | ipath_kreg kr_rcvegrcnt; | ||
| 344 | ipath_kreg kr_scratch; | ||
| 345 | ipath_kreg kr_sendctrl; | ||
| 346 | ipath_kreg kr_sendpiobufbase; | ||
| 347 | ipath_kreg kr_sendpiobufcnt; | ||
| 348 | ipath_kreg kr_sendpiosize; | ||
| 349 | ipath_kreg kr_sendregbase; | ||
| 350 | ipath_kreg kr_userregbase; | ||
| 351 | /* These are the 64 bit group */ | ||
| 352 | ipath_kreg kr_debugport; | ||
| 353 | ipath_kreg kr_debugportselect; | ||
| 354 | ipath_kreg kr_errorclear; | ||
| 355 | ipath_kreg kr_errormask; | ||
| 356 | ipath_kreg kr_errorstatus; | ||
| 357 | ipath_kreg kr_extctrl; | ||
| 358 | ipath_kreg kr_extstatus; | ||
| 359 | ipath_kreg kr_gpio_clear; | ||
| 360 | ipath_kreg kr_gpio_mask; | ||
| 361 | ipath_kreg kr_gpio_out; | ||
| 362 | ipath_kreg kr_gpio_status; | ||
| 363 | ipath_kreg kr_hwdiagctrl; | ||
| 364 | ipath_kreg kr_hwerrclear; | ||
| 365 | ipath_kreg kr_hwerrmask; | ||
| 366 | ipath_kreg kr_hwerrstatus; | ||
| 367 | ipath_kreg kr_ibcctrl; | ||
| 368 | ipath_kreg kr_ibcstatus; | ||
| 369 | ipath_kreg kr_intblocked; | ||
| 370 | ipath_kreg kr_intclear; | ||
| 371 | ipath_kreg kr_interruptconfig; | ||
| 372 | ipath_kreg kr_mdio; | ||
| 373 | ipath_kreg kr_partitionkey; | ||
| 374 | ipath_kreg kr_rcvbthqp; | ||
| 375 | ipath_kreg kr_rcvbufbase; | ||
| 376 | ipath_kreg kr_rcvbufsize; | ||
| 377 | ipath_kreg kr_rcvctrl; | ||
| 378 | ipath_kreg kr_rcvhdrcnt; | ||
| 379 | ipath_kreg kr_rcvhdrentsize; | ||
| 380 | ipath_kreg kr_rcvhdrsize; | ||
| 381 | ipath_kreg kr_rcvintmembase; | ||
| 382 | ipath_kreg kr_rcvintmemsize; | ||
| 383 | ipath_kreg kr_revision; | ||
| 384 | ipath_kreg kr_sendbuffererror; | ||
| 385 | ipath_kreg kr_sendpioavailaddr; | ||
| 386 | ipath_kreg kr_serdesconfig0; | ||
| 387 | ipath_kreg kr_serdesconfig1; | ||
| 388 | ipath_kreg kr_serdesstatus; | ||
| 389 | ipath_kreg kr_txintmembase; | ||
| 390 | ipath_kreg kr_txintmemsize; | ||
| 391 | ipath_kreg kr_xgxsconfig; | ||
| 392 | ipath_kreg kr_ibpllcfg; | ||
| 393 | /* use these two (and the following N ports) only with ipath_k*_kreg64_port(); | ||
| 394 | * not *kreg64() */ | ||
| 395 | ipath_kreg kr_rcvhdraddr; | ||
| 396 | ipath_kreg kr_rcvhdrtailaddr; | ||
| 397 | |||
| 398 | /* remaining registers are not present on all types of infinipath chips */ | ||
| 399 | ipath_kreg kr_rcvpktledcnt; | ||
| 400 | ipath_kreg kr_pcierbuftestreg0; | ||
| 401 | ipath_kreg kr_pcierbuftestreg1; | ||
| 402 | ipath_kreg kr_pcieq0serdesconfig0; | ||
| 403 | ipath_kreg kr_pcieq0serdesconfig1; | ||
| 404 | ipath_kreg kr_pcieq0serdesstatus; | ||
| 405 | ipath_kreg kr_pcieq1serdesconfig0; | ||
| 406 | ipath_kreg kr_pcieq1serdesconfig1; | ||
| 407 | ipath_kreg kr_pcieq1serdesstatus; | ||
| 408 | }; | ||
| 409 | |||
| 410 | struct ipath_cregs { | ||
| 411 | ipath_creg cr_badformatcnt; | ||
| 412 | ipath_creg cr_erricrccnt; | ||
| 413 | ipath_creg cr_errlinkcnt; | ||
| 414 | ipath_creg cr_errlpcrccnt; | ||
| 415 | ipath_creg cr_errpkey; | ||
| 416 | ipath_creg cr_errrcvflowctrlcnt; | ||
| 417 | ipath_creg cr_err_rlencnt; | ||
| 418 | ipath_creg cr_errslencnt; | ||
| 419 | ipath_creg cr_errtidfull; | ||
| 420 | ipath_creg cr_errtidvalid; | ||
| 421 | ipath_creg cr_errvcrccnt; | ||
| 422 | ipath_creg cr_ibstatuschange; | ||
| 423 | ipath_creg cr_intcnt; | ||
| 424 | ipath_creg cr_invalidrlencnt; | ||
| 425 | ipath_creg cr_invalidslencnt; | ||
| 426 | ipath_creg cr_lbflowstallcnt; | ||
| 427 | ipath_creg cr_iblinkdowncnt; | ||
| 428 | ipath_creg cr_iblinkerrrecovcnt; | ||
| 429 | ipath_creg cr_ibsymbolerrcnt; | ||
| 430 | ipath_creg cr_pktrcvcnt; | ||
| 431 | ipath_creg cr_pktrcvflowctrlcnt; | ||
| 432 | ipath_creg cr_pktsendcnt; | ||
| 433 | ipath_creg cr_pktsendflowcnt; | ||
| 434 | ipath_creg cr_portovflcnt; | ||
| 435 | ipath_creg cr_rcvebpcnt; | ||
| 436 | ipath_creg cr_rcvovflcnt; | ||
| 437 | ipath_creg cr_rxdroppktcnt; | ||
| 438 | ipath_creg cr_senddropped; | ||
| 439 | ipath_creg cr_sendstallcnt; | ||
| 440 | ipath_creg cr_sendunderruncnt; | ||
| 441 | ipath_creg cr_unsupvlcnt; | ||
| 442 | ipath_creg cr_wordrcvcnt; | ||
| 443 | ipath_creg cr_wordsendcnt; | ||
| 444 | }; | ||
| 445 | |||
| 446 | #endif /* _IPATH_REGISTERS_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c new file mode 100644 index 000000000000..f232e77b78ee --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
| @@ -0,0 +1,552 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "ipath_verbs.h" | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Convert the AETH RNR timeout code into the number of milliseconds. | ||
| 37 | */ | ||
| 38 | const u32 ib_ipath_rnr_table[32] = { | ||
| 39 | 656, /* 0 */ | ||
| 40 | 1, /* 1 */ | ||
| 41 | 1, /* 2 */ | ||
| 42 | 1, /* 3 */ | ||
| 43 | 1, /* 4 */ | ||
| 44 | 1, /* 5 */ | ||
| 45 | 1, /* 6 */ | ||
| 46 | 1, /* 7 */ | ||
| 47 | 1, /* 8 */ | ||
| 48 | 1, /* 9 */ | ||
| 49 | 1, /* A */ | ||
| 50 | 1, /* B */ | ||
| 51 | 1, /* C */ | ||
| 52 | 1, /* D */ | ||
| 53 | 2, /* E */ | ||
| 54 | 2, /* F */ | ||
| 55 | 3, /* 10 */ | ||
| 56 | 4, /* 11 */ | ||
| 57 | 6, /* 12 */ | ||
| 58 | 8, /* 13 */ | ||
| 59 | 11, /* 14 */ | ||
| 60 | 16, /* 15 */ | ||
| 61 | 21, /* 16 */ | ||
| 62 | 31, /* 17 */ | ||
| 63 | 41, /* 18 */ | ||
| 64 | 62, /* 19 */ | ||
| 65 | 82, /* 1A */ | ||
| 66 | 123, /* 1B */ | ||
| 67 | 164, /* 1C */ | ||
| 68 | 246, /* 1D */ | ||
| 69 | 328, /* 1E */ | ||
| 70 | 492 /* 1F */ | ||
| 71 | }; | ||
| 72 | |||
| 73 | /** | ||
| 74 | * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device | ||
| 75 | * @qp: the QP | ||
| 76 | * | ||
| 77 | * XXX Use a simple list for now. We might need a priority | ||
| 78 | * queue if we have lots of QPs waiting for RNR timeouts | ||
| 79 | * but that should be rare. | ||
| 80 | */ | ||
| 81 | void ipath_insert_rnr_queue(struct ipath_qp *qp) | ||
| 82 | { | ||
| 83 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 84 | unsigned long flags; | ||
| 85 | |||
| 86 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 87 | if (list_empty(&dev->rnrwait)) | ||
| 88 | list_add(&qp->timerwait, &dev->rnrwait); | ||
| 89 | else { | ||
| 90 | struct list_head *l = &dev->rnrwait; | ||
| 91 | struct ipath_qp *nqp = list_entry(l->next, struct ipath_qp, | ||
| 92 | timerwait); | ||
| 93 | |||
| 94 | while (qp->s_rnr_timeout >= nqp->s_rnr_timeout) { | ||
| 95 | qp->s_rnr_timeout -= nqp->s_rnr_timeout; | ||
| 96 | l = l->next; | ||
| 97 | if (l->next == &dev->rnrwait) | ||
| 98 | break; | ||
| 99 | nqp = list_entry(l->next, struct ipath_qp, | ||
| 100 | timerwait); | ||
| 101 | } | ||
| 102 | list_add(&qp->timerwait, l); | ||
| 103 | } | ||
| 104 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * ipath_get_rwqe - copy the next RWQE into the QP's RWQE | ||
| 109 | * @qp: the QP | ||
| 110 | * @wr_id_only: update wr_id only, not SGEs | ||
| 111 | * | ||
| 112 | * Return 0 if no RWQE is available, otherwise return 1. | ||
| 113 | * | ||
| 114 | * Called at interrupt level with the QP r_rq.lock held. | ||
| 115 | */ | ||
| 116 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | ||
| 117 | { | ||
| 118 | struct ipath_rq *rq; | ||
| 119 | struct ipath_srq *srq; | ||
| 120 | struct ipath_rwqe *wqe; | ||
| 121 | int ret; | ||
| 122 | |||
| 123 | if (!qp->ibqp.srq) { | ||
| 124 | rq = &qp->r_rq; | ||
| 125 | if (unlikely(rq->tail == rq->head)) { | ||
| 126 | ret = 0; | ||
| 127 | goto bail; | ||
| 128 | } | ||
| 129 | wqe = get_rwqe_ptr(rq, rq->tail); | ||
| 130 | qp->r_wr_id = wqe->wr_id; | ||
| 131 | if (!wr_id_only) { | ||
| 132 | qp->r_sge.sge = wqe->sg_list[0]; | ||
| 133 | qp->r_sge.sg_list = wqe->sg_list + 1; | ||
| 134 | qp->r_sge.num_sge = wqe->num_sge; | ||
| 135 | qp->r_len = wqe->length; | ||
| 136 | } | ||
| 137 | if (++rq->tail >= rq->size) | ||
| 138 | rq->tail = 0; | ||
| 139 | ret = 1; | ||
| 140 | goto bail; | ||
| 141 | } | ||
| 142 | |||
| 143 | srq = to_isrq(qp->ibqp.srq); | ||
| 144 | rq = &srq->rq; | ||
| 145 | spin_lock(&rq->lock); | ||
| 146 | if (unlikely(rq->tail == rq->head)) { | ||
| 147 | spin_unlock(&rq->lock); | ||
| 148 | ret = 0; | ||
| 149 | goto bail; | ||
| 150 | } | ||
| 151 | wqe = get_rwqe_ptr(rq, rq->tail); | ||
| 152 | qp->r_wr_id = wqe->wr_id; | ||
| 153 | if (!wr_id_only) { | ||
| 154 | qp->r_sge.sge = wqe->sg_list[0]; | ||
| 155 | qp->r_sge.sg_list = wqe->sg_list + 1; | ||
| 156 | qp->r_sge.num_sge = wqe->num_sge; | ||
| 157 | qp->r_len = wqe->length; | ||
| 158 | } | ||
| 159 | if (++rq->tail >= rq->size) | ||
| 160 | rq->tail = 0; | ||
| 161 | if (srq->ibsrq.event_handler) { | ||
| 162 | struct ib_event ev; | ||
| 163 | u32 n; | ||
| 164 | |||
| 165 | if (rq->head < rq->tail) | ||
| 166 | n = rq->size + rq->head - rq->tail; | ||
| 167 | else | ||
| 168 | n = rq->head - rq->tail; | ||
| 169 | if (n < srq->limit) { | ||
| 170 | srq->limit = 0; | ||
| 171 | spin_unlock(&rq->lock); | ||
| 172 | ev.device = qp->ibqp.device; | ||
| 173 | ev.element.srq = qp->ibqp.srq; | ||
| 174 | ev.event = IB_EVENT_SRQ_LIMIT_REACHED; | ||
| 175 | srq->ibsrq.event_handler(&ev, | ||
| 176 | srq->ibsrq.srq_context); | ||
| 177 | } else | ||
| 178 | spin_unlock(&rq->lock); | ||
| 179 | } else | ||
| 180 | spin_unlock(&rq->lock); | ||
| 181 | ret = 1; | ||
| 182 | |||
| 183 | bail: | ||
| 184 | return ret; | ||
| 185 | } | ||
| 186 | |||
| 187 | /** | ||
| 188 | * ipath_ruc_loopback - handle UC and RC lookback requests | ||
| 189 | * @sqp: the loopback QP | ||
| 190 | * @wc: the work completion entry | ||
| 191 | * | ||
| 192 | * This is called from ipath_do_uc_send() or ipath_do_rc_send() to | ||
| 193 | * forward a WQE addressed to the same HCA. | ||
| 194 | * Note that although we are single threaded due to the tasklet, we still | ||
| 195 | * have to protect against post_send(). We don't have to worry about | ||
| 196 | * receive interrupts since this is a connected protocol and all packets | ||
| 197 | * will pass through here. | ||
| 198 | */ | ||
| 199 | void ipath_ruc_loopback(struct ipath_qp *sqp, struct ib_wc *wc) | ||
| 200 | { | ||
| 201 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | ||
| 202 | struct ipath_qp *qp; | ||
| 203 | struct ipath_swqe *wqe; | ||
| 204 | struct ipath_sge *sge; | ||
| 205 | unsigned long flags; | ||
| 206 | u64 sdata; | ||
| 207 | |||
| 208 | qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn); | ||
| 209 | if (!qp) { | ||
| 210 | dev->n_pkt_drops++; | ||
| 211 | return; | ||
| 212 | } | ||
| 213 | |||
| 214 | again: | ||
| 215 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
| 216 | |||
| 217 | if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK)) { | ||
| 218 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
| 219 | goto done; | ||
| 220 | } | ||
| 221 | |||
| 222 | /* Get the next send request. */ | ||
| 223 | if (sqp->s_last == sqp->s_head) { | ||
| 224 | /* Send work queue is empty. */ | ||
| 225 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
| 226 | goto done; | ||
| 227 | } | ||
| 228 | |||
| 229 | /* | ||
| 230 | * We can rely on the entry not changing without the s_lock | ||
| 231 | * being held until we update s_last. | ||
| 232 | */ | ||
| 233 | wqe = get_swqe_ptr(sqp, sqp->s_last); | ||
| 234 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
| 235 | |||
| 236 | wc->wc_flags = 0; | ||
| 237 | wc->imm_data = 0; | ||
| 238 | |||
| 239 | sqp->s_sge.sge = wqe->sg_list[0]; | ||
| 240 | sqp->s_sge.sg_list = wqe->sg_list + 1; | ||
| 241 | sqp->s_sge.num_sge = wqe->wr.num_sge; | ||
| 242 | sqp->s_len = wqe->length; | ||
| 243 | switch (wqe->wr.opcode) { | ||
| 244 | case IB_WR_SEND_WITH_IMM: | ||
| 245 | wc->wc_flags = IB_WC_WITH_IMM; | ||
| 246 | wc->imm_data = wqe->wr.imm_data; | ||
| 247 | /* FALLTHROUGH */ | ||
| 248 | case IB_WR_SEND: | ||
| 249 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 250 | if (!ipath_get_rwqe(qp, 0)) { | ||
| 251 | rnr_nak: | ||
| 252 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 253 | /* Handle RNR NAK */ | ||
| 254 | if (qp->ibqp.qp_type == IB_QPT_UC) | ||
| 255 | goto send_comp; | ||
| 256 | if (sqp->s_rnr_retry == 0) { | ||
| 257 | wc->status = IB_WC_RNR_RETRY_EXC_ERR; | ||
| 258 | goto err; | ||
| 259 | } | ||
| 260 | if (sqp->s_rnr_retry_cnt < 7) | ||
| 261 | sqp->s_rnr_retry--; | ||
| 262 | dev->n_rnr_naks++; | ||
| 263 | sqp->s_rnr_timeout = | ||
| 264 | ib_ipath_rnr_table[sqp->s_min_rnr_timer]; | ||
| 265 | ipath_insert_rnr_queue(sqp); | ||
| 266 | goto done; | ||
| 267 | } | ||
| 268 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 269 | break; | ||
| 270 | |||
| 271 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
| 272 | wc->wc_flags = IB_WC_WITH_IMM; | ||
| 273 | wc->imm_data = wqe->wr.imm_data; | ||
| 274 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 275 | if (!ipath_get_rwqe(qp, 1)) | ||
| 276 | goto rnr_nak; | ||
| 277 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 278 | /* FALLTHROUGH */ | ||
| 279 | case IB_WR_RDMA_WRITE: | ||
| 280 | if (wqe->length == 0) | ||
| 281 | break; | ||
| 282 | if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length, | ||
| 283 | wqe->wr.wr.rdma.remote_addr, | ||
| 284 | wqe->wr.wr.rdma.rkey, | ||
| 285 | IB_ACCESS_REMOTE_WRITE))) { | ||
| 286 | acc_err: | ||
| 287 | wc->status = IB_WC_REM_ACCESS_ERR; | ||
| 288 | err: | ||
| 289 | wc->wr_id = wqe->wr.wr_id; | ||
| 290 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 291 | wc->vendor_err = 0; | ||
| 292 | wc->byte_len = 0; | ||
| 293 | wc->qp_num = sqp->ibqp.qp_num; | ||
| 294 | wc->src_qp = sqp->remote_qpn; | ||
| 295 | wc->pkey_index = 0; | ||
| 296 | wc->slid = sqp->remote_ah_attr.dlid; | ||
| 297 | wc->sl = sqp->remote_ah_attr.sl; | ||
| 298 | wc->dlid_path_bits = 0; | ||
| 299 | wc->port_num = 0; | ||
| 300 | ipath_sqerror_qp(sqp, wc); | ||
| 301 | goto done; | ||
| 302 | } | ||
| 303 | break; | ||
| 304 | |||
| 305 | case IB_WR_RDMA_READ: | ||
| 306 | if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length, | ||
| 307 | wqe->wr.wr.rdma.remote_addr, | ||
| 308 | wqe->wr.wr.rdma.rkey, | ||
| 309 | IB_ACCESS_REMOTE_READ))) | ||
| 310 | goto acc_err; | ||
| 311 | if (unlikely(!(qp->qp_access_flags & | ||
| 312 | IB_ACCESS_REMOTE_READ))) | ||
| 313 | goto acc_err; | ||
| 314 | qp->r_sge.sge = wqe->sg_list[0]; | ||
| 315 | qp->r_sge.sg_list = wqe->sg_list + 1; | ||
| 316 | qp->r_sge.num_sge = wqe->wr.num_sge; | ||
| 317 | break; | ||
| 318 | |||
| 319 | case IB_WR_ATOMIC_CMP_AND_SWP: | ||
| 320 | case IB_WR_ATOMIC_FETCH_AND_ADD: | ||
| 321 | if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64), | ||
| 322 | wqe->wr.wr.rdma.remote_addr, | ||
| 323 | wqe->wr.wr.rdma.rkey, | ||
| 324 | IB_ACCESS_REMOTE_ATOMIC))) | ||
| 325 | goto acc_err; | ||
| 326 | /* Perform atomic OP and save result. */ | ||
| 327 | sdata = wqe->wr.wr.atomic.swap; | ||
| 328 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 329 | qp->r_atomic_data = *(u64 *) qp->r_sge.sge.vaddr; | ||
| 330 | if (wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) | ||
| 331 | *(u64 *) qp->r_sge.sge.vaddr = | ||
| 332 | qp->r_atomic_data + sdata; | ||
| 333 | else if (qp->r_atomic_data == wqe->wr.wr.atomic.compare_add) | ||
| 334 | *(u64 *) qp->r_sge.sge.vaddr = sdata; | ||
| 335 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 336 | *(u64 *) sqp->s_sge.sge.vaddr = qp->r_atomic_data; | ||
| 337 | goto send_comp; | ||
| 338 | |||
| 339 | default: | ||
| 340 | goto done; | ||
| 341 | } | ||
| 342 | |||
| 343 | sge = &sqp->s_sge.sge; | ||
| 344 | while (sqp->s_len) { | ||
| 345 | u32 len = sqp->s_len; | ||
| 346 | |||
| 347 | if (len > sge->length) | ||
| 348 | len = sge->length; | ||
| 349 | BUG_ON(len == 0); | ||
| 350 | ipath_copy_sge(&qp->r_sge, sge->vaddr, len); | ||
| 351 | sge->vaddr += len; | ||
| 352 | sge->length -= len; | ||
| 353 | sge->sge_length -= len; | ||
| 354 | if (sge->sge_length == 0) { | ||
| 355 | if (--sqp->s_sge.num_sge) | ||
| 356 | *sge = *sqp->s_sge.sg_list++; | ||
| 357 | } else if (sge->length == 0 && sge->mr != NULL) { | ||
| 358 | if (++sge->n >= IPATH_SEGSZ) { | ||
| 359 | if (++sge->m >= sge->mr->mapsz) | ||
| 360 | break; | ||
| 361 | sge->n = 0; | ||
| 362 | } | ||
| 363 | sge->vaddr = | ||
| 364 | sge->mr->map[sge->m]->segs[sge->n].vaddr; | ||
| 365 | sge->length = | ||
| 366 | sge->mr->map[sge->m]->segs[sge->n].length; | ||
| 367 | } | ||
| 368 | sqp->s_len -= len; | ||
| 369 | } | ||
| 370 | |||
| 371 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE || | ||
| 372 | wqe->wr.opcode == IB_WR_RDMA_READ) | ||
| 373 | goto send_comp; | ||
| 374 | |||
| 375 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM) | ||
| 376 | wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; | ||
| 377 | else | ||
| 378 | wc->opcode = IB_WC_RECV; | ||
| 379 | wc->wr_id = qp->r_wr_id; | ||
| 380 | wc->status = IB_WC_SUCCESS; | ||
| 381 | wc->vendor_err = 0; | ||
| 382 | wc->byte_len = wqe->length; | ||
| 383 | wc->qp_num = qp->ibqp.qp_num; | ||
| 384 | wc->src_qp = qp->remote_qpn; | ||
| 385 | /* XXX do we know which pkey matched? Only needed for GSI. */ | ||
| 386 | wc->pkey_index = 0; | ||
| 387 | wc->slid = qp->remote_ah_attr.dlid; | ||
| 388 | wc->sl = qp->remote_ah_attr.sl; | ||
| 389 | wc->dlid_path_bits = 0; | ||
| 390 | /* Signal completion event if the solicited bit is set. */ | ||
| 391 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc, | ||
| 392 | wqe->wr.send_flags & IB_SEND_SOLICITED); | ||
| 393 | |||
| 394 | send_comp: | ||
| 395 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; | ||
| 396 | |||
| 397 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &sqp->s_flags) || | ||
| 398 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
| 399 | wc->wr_id = wqe->wr.wr_id; | ||
| 400 | wc->status = IB_WC_SUCCESS; | ||
| 401 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 402 | wc->vendor_err = 0; | ||
| 403 | wc->byte_len = wqe->length; | ||
| 404 | wc->qp_num = sqp->ibqp.qp_num; | ||
| 405 | wc->src_qp = 0; | ||
| 406 | wc->pkey_index = 0; | ||
| 407 | wc->slid = 0; | ||
| 408 | wc->sl = 0; | ||
| 409 | wc->dlid_path_bits = 0; | ||
| 410 | wc->port_num = 0; | ||
| 411 | ipath_cq_enter(to_icq(sqp->ibqp.send_cq), wc, 0); | ||
| 412 | } | ||
| 413 | |||
| 414 | /* Update s_last now that we are finished with the SWQE */ | ||
| 415 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
| 416 | if (++sqp->s_last >= sqp->s_size) | ||
| 417 | sqp->s_last = 0; | ||
| 418 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
| 419 | goto again; | ||
| 420 | |||
| 421 | done: | ||
| 422 | if (atomic_dec_and_test(&qp->refcount)) | ||
| 423 | wake_up(&qp->wait); | ||
| 424 | } | ||
| 425 | |||
| 426 | /** | ||
| 427 | * ipath_no_bufs_available - tell the layer driver we need buffers | ||
| 428 | * @qp: the QP that caused the problem | ||
| 429 | * @dev: the device we ran out of buffers on | ||
| 430 | * | ||
| 431 | * Called when we run out of PIO buffers. | ||
| 432 | */ | ||
| 433 | void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev) | ||
| 434 | { | ||
| 435 | unsigned long flags; | ||
| 436 | |||
| 437 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 438 | if (qp->piowait.next == LIST_POISON1) | ||
| 439 | list_add_tail(&qp->piowait, &dev->piowait); | ||
| 440 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 441 | /* | ||
| 442 | * Note that as soon as ipath_layer_want_buffer() is called and | ||
| 443 | * possibly before it returns, ipath_ib_piobufavail() | ||
| 444 | * could be called. If we are still in the tasklet function, | ||
| 445 | * tasklet_hi_schedule() will not call us until the next time | ||
| 446 | * tasklet_hi_schedule() is called. | ||
| 447 | * We clear the tasklet flag now since we are committing to return | ||
| 448 | * from the tasklet function. | ||
| 449 | */ | ||
| 450 | clear_bit(IPATH_S_BUSY, &qp->s_flags); | ||
| 451 | tasklet_unlock(&qp->s_task); | ||
| 452 | ipath_layer_want_buffer(dev->dd); | ||
| 453 | dev->n_piowait++; | ||
| 454 | } | ||
| 455 | |||
| 456 | /** | ||
| 457 | * ipath_post_rc_send - post RC and UC sends | ||
| 458 | * @qp: the QP to post on | ||
| 459 | * @wr: the work request to send | ||
| 460 | */ | ||
| 461 | int ipath_post_rc_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
| 462 | { | ||
| 463 | struct ipath_swqe *wqe; | ||
| 464 | unsigned long flags; | ||
| 465 | u32 next; | ||
| 466 | int i, j; | ||
| 467 | int acc; | ||
| 468 | int ret; | ||
| 469 | |||
| 470 | /* | ||
| 471 | * Don't allow RDMA reads or atomic operations on UC or | ||
| 472 | * undefined operations. | ||
| 473 | * Make sure buffer is large enough to hold the result for atomics. | ||
| 474 | */ | ||
| 475 | if (qp->ibqp.qp_type == IB_QPT_UC) { | ||
| 476 | if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) { | ||
| 477 | ret = -EINVAL; | ||
| 478 | goto bail; | ||
| 479 | } | ||
| 480 | } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) { | ||
| 481 | ret = -EINVAL; | ||
| 482 | goto bail; | ||
| 483 | } else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && | ||
| 484 | (wr->num_sge == 0 || | ||
| 485 | wr->sg_list[0].length < sizeof(u64) || | ||
| 486 | wr->sg_list[0].addr & (sizeof(u64) - 1))) { | ||
| 487 | ret = -EINVAL; | ||
| 488 | goto bail; | ||
| 489 | } | ||
| 490 | /* IB spec says that num_sge == 0 is OK. */ | ||
| 491 | if (wr->num_sge > qp->s_max_sge) { | ||
| 492 | ret = -ENOMEM; | ||
| 493 | goto bail; | ||
| 494 | } | ||
| 495 | spin_lock_irqsave(&qp->s_lock, flags); | ||
| 496 | next = qp->s_head + 1; | ||
| 497 | if (next >= qp->s_size) | ||
| 498 | next = 0; | ||
| 499 | if (next == qp->s_last) { | ||
| 500 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 501 | ret = -EINVAL; | ||
| 502 | goto bail; | ||
| 503 | } | ||
| 504 | |||
| 505 | wqe = get_swqe_ptr(qp, qp->s_head); | ||
| 506 | wqe->wr = *wr; | ||
| 507 | wqe->ssn = qp->s_ssn++; | ||
| 508 | wqe->sg_list[0].mr = NULL; | ||
| 509 | wqe->sg_list[0].vaddr = NULL; | ||
| 510 | wqe->sg_list[0].length = 0; | ||
| 511 | wqe->sg_list[0].sge_length = 0; | ||
| 512 | wqe->length = 0; | ||
| 513 | acc = wr->opcode >= IB_WR_RDMA_READ ? IB_ACCESS_LOCAL_WRITE : 0; | ||
| 514 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
| 515 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
| 516 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 517 | ret = -EINVAL; | ||
| 518 | goto bail; | ||
| 519 | } | ||
| 520 | if (wr->sg_list[i].length == 0) | ||
| 521 | continue; | ||
| 522 | if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table, | ||
| 523 | &wqe->sg_list[j], &wr->sg_list[i], | ||
| 524 | acc)) { | ||
| 525 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 526 | ret = -EINVAL; | ||
| 527 | goto bail; | ||
| 528 | } | ||
| 529 | wqe->length += wr->sg_list[i].length; | ||
| 530 | j++; | ||
| 531 | } | ||
| 532 | wqe->wr.num_sge = j; | ||
| 533 | qp->s_head = next; | ||
| 534 | /* | ||
| 535 | * Wake up the send tasklet if the QP is not waiting | ||
| 536 | * for an RNR timeout. | ||
| 537 | */ | ||
| 538 | next = qp->s_rnr_timeout; | ||
| 539 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 540 | |||
| 541 | if (next == 0) { | ||
| 542 | if (qp->ibqp.qp_type == IB_QPT_UC) | ||
| 543 | ipath_do_uc_send((unsigned long) qp); | ||
| 544 | else | ||
| 545 | ipath_do_rc_send((unsigned long) qp); | ||
| 546 | } | ||
| 547 | |||
| 548 | ret = 0; | ||
| 549 | |||
| 550 | bail: | ||
| 551 | return ret; | ||
| 552 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c new file mode 100644 index 000000000000..01c4c6c56118 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_srq.c | |||
| @@ -0,0 +1,273 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/err.h> | ||
| 34 | #include <linux/vmalloc.h> | ||
| 35 | |||
| 36 | #include "ipath_verbs.h" | ||
| 37 | |||
| 38 | /** | ||
| 39 | * ipath_post_srq_receive - post a receive on a shared receive queue | ||
| 40 | * @ibsrq: the SRQ to post the receive on | ||
| 41 | * @wr: the list of work requests to post | ||
| 42 | * @bad_wr: the first WR to cause a problem is put here | ||
| 43 | * | ||
| 44 | * This may be called from interrupt context. | ||
| 45 | */ | ||
| 46 | int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | ||
| 47 | struct ib_recv_wr **bad_wr) | ||
| 48 | { | ||
| 49 | struct ipath_srq *srq = to_isrq(ibsrq); | ||
| 50 | struct ipath_ibdev *dev = to_idev(ibsrq->device); | ||
| 51 | unsigned long flags; | ||
| 52 | int ret; | ||
| 53 | |||
| 54 | for (; wr; wr = wr->next) { | ||
| 55 | struct ipath_rwqe *wqe; | ||
| 56 | u32 next; | ||
| 57 | int i, j; | ||
| 58 | |||
| 59 | if (wr->num_sge > srq->rq.max_sge) { | ||
| 60 | *bad_wr = wr; | ||
| 61 | ret = -ENOMEM; | ||
| 62 | goto bail; | ||
| 63 | } | ||
| 64 | |||
| 65 | spin_lock_irqsave(&srq->rq.lock, flags); | ||
| 66 | next = srq->rq.head + 1; | ||
| 67 | if (next >= srq->rq.size) | ||
| 68 | next = 0; | ||
| 69 | if (next == srq->rq.tail) { | ||
| 70 | spin_unlock_irqrestore(&srq->rq.lock, flags); | ||
| 71 | *bad_wr = wr; | ||
| 72 | ret = -ENOMEM; | ||
| 73 | goto bail; | ||
| 74 | } | ||
| 75 | |||
| 76 | wqe = get_rwqe_ptr(&srq->rq, srq->rq.head); | ||
| 77 | wqe->wr_id = wr->wr_id; | ||
| 78 | wqe->sg_list[0].mr = NULL; | ||
| 79 | wqe->sg_list[0].vaddr = NULL; | ||
| 80 | wqe->sg_list[0].length = 0; | ||
| 81 | wqe->sg_list[0].sge_length = 0; | ||
| 82 | wqe->length = 0; | ||
| 83 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
| 84 | /* Check LKEY */ | ||
| 85 | if (to_ipd(srq->ibsrq.pd)->user && | ||
| 86 | wr->sg_list[i].lkey == 0) { | ||
| 87 | spin_unlock_irqrestore(&srq->rq.lock, | ||
| 88 | flags); | ||
| 89 | *bad_wr = wr; | ||
| 90 | ret = -EINVAL; | ||
| 91 | goto bail; | ||
| 92 | } | ||
| 93 | if (wr->sg_list[i].length == 0) | ||
| 94 | continue; | ||
| 95 | if (!ipath_lkey_ok(&dev->lk_table, | ||
| 96 | &wqe->sg_list[j], | ||
| 97 | &wr->sg_list[i], | ||
| 98 | IB_ACCESS_LOCAL_WRITE)) { | ||
| 99 | spin_unlock_irqrestore(&srq->rq.lock, | ||
| 100 | flags); | ||
| 101 | *bad_wr = wr; | ||
| 102 | ret = -EINVAL; | ||
| 103 | goto bail; | ||
| 104 | } | ||
| 105 | wqe->length += wr->sg_list[i].length; | ||
| 106 | j++; | ||
| 107 | } | ||
| 108 | wqe->num_sge = j; | ||
| 109 | srq->rq.head = next; | ||
| 110 | spin_unlock_irqrestore(&srq->rq.lock, flags); | ||
| 111 | } | ||
| 112 | ret = 0; | ||
| 113 | |||
| 114 | bail: | ||
| 115 | return ret; | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | ||
| 119 | * ipath_create_srq - create a shared receive queue | ||
| 120 | * @ibpd: the protection domain of the SRQ to create | ||
| 121 | * @attr: the attributes of the SRQ | ||
| 122 | * @udata: not used by the InfiniPath verbs driver | ||
| 123 | */ | ||
| 124 | struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, | ||
| 125 | struct ib_srq_init_attr *srq_init_attr, | ||
| 126 | struct ib_udata *udata) | ||
| 127 | { | ||
| 128 | struct ipath_srq *srq; | ||
| 129 | u32 sz; | ||
| 130 | struct ib_srq *ret; | ||
| 131 | |||
| 132 | if (srq_init_attr->attr.max_sge < 1) { | ||
| 133 | ret = ERR_PTR(-EINVAL); | ||
| 134 | goto bail; | ||
| 135 | } | ||
| 136 | |||
| 137 | srq = kmalloc(sizeof(*srq), GFP_KERNEL); | ||
| 138 | if (!srq) { | ||
| 139 | ret = ERR_PTR(-ENOMEM); | ||
| 140 | goto bail; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Need to use vmalloc() if we want to support large #s of entries. | ||
| 145 | */ | ||
| 146 | srq->rq.size = srq_init_attr->attr.max_wr + 1; | ||
| 147 | sz = sizeof(struct ipath_sge) * srq_init_attr->attr.max_sge + | ||
| 148 | sizeof(struct ipath_rwqe); | ||
| 149 | srq->rq.wq = vmalloc(srq->rq.size * sz); | ||
| 150 | if (!srq->rq.wq) { | ||
| 151 | kfree(srq); | ||
| 152 | ret = ERR_PTR(-ENOMEM); | ||
| 153 | goto bail; | ||
| 154 | } | ||
| 155 | |||
| 156 | /* | ||
| 157 | * ib_create_srq() will initialize srq->ibsrq. | ||
| 158 | */ | ||
| 159 | spin_lock_init(&srq->rq.lock); | ||
| 160 | srq->rq.head = 0; | ||
| 161 | srq->rq.tail = 0; | ||
| 162 | srq->rq.max_sge = srq_init_attr->attr.max_sge; | ||
| 163 | srq->limit = srq_init_attr->attr.srq_limit; | ||
| 164 | |||
| 165 | ret = &srq->ibsrq; | ||
| 166 | |||
| 167 | bail: | ||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * ipath_modify_srq - modify a shared receive queue | ||
| 173 | * @ibsrq: the SRQ to modify | ||
| 174 | * @attr: the new attributes of the SRQ | ||
| 175 | * @attr_mask: indicates which attributes to modify | ||
| 176 | */ | ||
| 177 | int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | ||
| 178 | enum ib_srq_attr_mask attr_mask) | ||
| 179 | { | ||
| 180 | struct ipath_srq *srq = to_isrq(ibsrq); | ||
| 181 | unsigned long flags; | ||
| 182 | int ret; | ||
| 183 | |||
| 184 | if (attr_mask & IB_SRQ_LIMIT) { | ||
| 185 | spin_lock_irqsave(&srq->rq.lock, flags); | ||
| 186 | srq->limit = attr->srq_limit; | ||
| 187 | spin_unlock_irqrestore(&srq->rq.lock, flags); | ||
| 188 | } | ||
| 189 | if (attr_mask & IB_SRQ_MAX_WR) { | ||
| 190 | u32 size = attr->max_wr + 1; | ||
| 191 | struct ipath_rwqe *wq, *p; | ||
| 192 | u32 n; | ||
| 193 | u32 sz; | ||
| 194 | |||
| 195 | if (attr->max_sge < srq->rq.max_sge) { | ||
| 196 | ret = -EINVAL; | ||
| 197 | goto bail; | ||
| 198 | } | ||
| 199 | |||
| 200 | sz = sizeof(struct ipath_rwqe) + | ||
| 201 | attr->max_sge * sizeof(struct ipath_sge); | ||
| 202 | wq = vmalloc(size * sz); | ||
| 203 | if (!wq) { | ||
| 204 | ret = -ENOMEM; | ||
| 205 | goto bail; | ||
| 206 | } | ||
| 207 | |||
| 208 | spin_lock_irqsave(&srq->rq.lock, flags); | ||
| 209 | if (srq->rq.head < srq->rq.tail) | ||
| 210 | n = srq->rq.size + srq->rq.head - srq->rq.tail; | ||
| 211 | else | ||
| 212 | n = srq->rq.head - srq->rq.tail; | ||
| 213 | if (size <= n || size <= srq->limit) { | ||
| 214 | spin_unlock_irqrestore(&srq->rq.lock, flags); | ||
| 215 | vfree(wq); | ||
| 216 | ret = -EINVAL; | ||
| 217 | goto bail; | ||
| 218 | } | ||
| 219 | n = 0; | ||
| 220 | p = wq; | ||
| 221 | while (srq->rq.tail != srq->rq.head) { | ||
| 222 | struct ipath_rwqe *wqe; | ||
| 223 | int i; | ||
| 224 | |||
| 225 | wqe = get_rwqe_ptr(&srq->rq, srq->rq.tail); | ||
| 226 | p->wr_id = wqe->wr_id; | ||
| 227 | p->length = wqe->length; | ||
| 228 | p->num_sge = wqe->num_sge; | ||
| 229 | for (i = 0; i < wqe->num_sge; i++) | ||
| 230 | p->sg_list[i] = wqe->sg_list[i]; | ||
| 231 | n++; | ||
| 232 | p = (struct ipath_rwqe *)((char *) p + sz); | ||
| 233 | if (++srq->rq.tail >= srq->rq.size) | ||
| 234 | srq->rq.tail = 0; | ||
| 235 | } | ||
| 236 | vfree(srq->rq.wq); | ||
| 237 | srq->rq.wq = wq; | ||
| 238 | srq->rq.size = size; | ||
| 239 | srq->rq.head = n; | ||
| 240 | srq->rq.tail = 0; | ||
| 241 | srq->rq.max_sge = attr->max_sge; | ||
| 242 | spin_unlock_irqrestore(&srq->rq.lock, flags); | ||
| 243 | } | ||
| 244 | |||
| 245 | ret = 0; | ||
| 246 | |||
| 247 | bail: | ||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | |||
| 251 | int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) | ||
| 252 | { | ||
| 253 | struct ipath_srq *srq = to_isrq(ibsrq); | ||
| 254 | |||
| 255 | attr->max_wr = srq->rq.size - 1; | ||
| 256 | attr->max_sge = srq->rq.max_sge; | ||
| 257 | attr->srq_limit = srq->limit; | ||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * ipath_destroy_srq - destroy a shared receive queue | ||
| 263 | * @ibsrq: the SRQ to destroy | ||
| 264 | */ | ||
| 265 | int ipath_destroy_srq(struct ib_srq *ibsrq) | ||
| 266 | { | ||
| 267 | struct ipath_srq *srq = to_isrq(ibsrq); | ||
| 268 | |||
| 269 | vfree(srq->rq.wq); | ||
| 270 | kfree(srq); | ||
| 271 | |||
| 272 | return 0; | ||
| 273 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c new file mode 100644 index 000000000000..fe209137ee74 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_stats.c | |||
| @@ -0,0 +1,303 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/pci.h> | ||
| 34 | |||
| 35 | #include "ipath_kernel.h" | ||
| 36 | |||
| 37 | struct infinipath_stats ipath_stats; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * ipath_snap_cntr - snapshot a chip counter | ||
| 41 | * @dd: the infinipath device | ||
| 42 | * @creg: the counter to snapshot | ||
| 43 | * | ||
| 44 | * called from add_timer and user counter read calls, to deal with | ||
| 45 | * counters that wrap in "human time". The words sent and received, and | ||
| 46 | * the packets sent and received are all that we worry about. For now, | ||
| 47 | * at least, we don't worry about error counters, because if they wrap | ||
| 48 | * that quickly, we probably don't care. We may eventually just make this | ||
| 49 | * handle all the counters. word counters can wrap in about 20 seconds | ||
| 50 | * of full bandwidth traffic, packet counters in a few hours. | ||
| 51 | */ | ||
| 52 | |||
| 53 | u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg) | ||
| 54 | { | ||
| 55 | u32 val, reg64 = 0; | ||
| 56 | u64 val64; | ||
| 57 | unsigned long t0, t1; | ||
| 58 | u64 ret; | ||
| 59 | |||
| 60 | t0 = jiffies; | ||
| 61 | /* If fast increment counters are only 32 bits, snapshot them, | ||
| 62 | * and maintain them as 64bit values in the driver */ | ||
| 63 | if (!(dd->ipath_flags & IPATH_32BITCOUNTERS) && | ||
| 64 | (creg == dd->ipath_cregs->cr_wordsendcnt || | ||
| 65 | creg == dd->ipath_cregs->cr_wordrcvcnt || | ||
| 66 | creg == dd->ipath_cregs->cr_pktsendcnt || | ||
| 67 | creg == dd->ipath_cregs->cr_pktrcvcnt)) { | ||
| 68 | val64 = ipath_read_creg(dd, creg); | ||
| 69 | val = val64 == ~0ULL ? ~0U : 0; | ||
| 70 | reg64 = 1; | ||
| 71 | } else /* val64 just to keep gcc quiet... */ | ||
| 72 | val64 = val = ipath_read_creg32(dd, creg); | ||
| 73 | /* | ||
| 74 | * See if a second has passed. This is just a way to detect things | ||
| 75 | * that are quite broken. Normally this should take just a few | ||
| 76 | * cycles (the check is for long enough that we don't care if we get | ||
| 77 | * pre-empted.) An Opteron HT O read timeout is 4 seconds with | ||
| 78 | * normal NB values | ||
| 79 | */ | ||
| 80 | t1 = jiffies; | ||
| 81 | if (time_before(t0 + HZ, t1) && val == -1) { | ||
| 82 | ipath_dev_err(dd, "Error! Read counter 0x%x timed out\n", | ||
| 83 | creg); | ||
| 84 | ret = 0ULL; | ||
| 85 | goto bail; | ||
| 86 | } | ||
| 87 | if (reg64) { | ||
| 88 | ret = val64; | ||
| 89 | goto bail; | ||
| 90 | } | ||
| 91 | |||
| 92 | if (creg == dd->ipath_cregs->cr_wordsendcnt) { | ||
| 93 | if (val != dd->ipath_lastsword) { | ||
| 94 | dd->ipath_sword += val - dd->ipath_lastsword; | ||
| 95 | dd->ipath_lastsword = val; | ||
| 96 | } | ||
| 97 | val64 = dd->ipath_sword; | ||
| 98 | } else if (creg == dd->ipath_cregs->cr_wordrcvcnt) { | ||
| 99 | if (val != dd->ipath_lastrword) { | ||
| 100 | dd->ipath_rword += val - dd->ipath_lastrword; | ||
| 101 | dd->ipath_lastrword = val; | ||
| 102 | } | ||
| 103 | val64 = dd->ipath_rword; | ||
| 104 | } else if (creg == dd->ipath_cregs->cr_pktsendcnt) { | ||
| 105 | if (val != dd->ipath_lastspkts) { | ||
| 106 | dd->ipath_spkts += val - dd->ipath_lastspkts; | ||
| 107 | dd->ipath_lastspkts = val; | ||
| 108 | } | ||
| 109 | val64 = dd->ipath_spkts; | ||
| 110 | } else if (creg == dd->ipath_cregs->cr_pktrcvcnt) { | ||
| 111 | if (val != dd->ipath_lastrpkts) { | ||
| 112 | dd->ipath_rpkts += val - dd->ipath_lastrpkts; | ||
| 113 | dd->ipath_lastrpkts = val; | ||
| 114 | } | ||
| 115 | val64 = dd->ipath_rpkts; | ||
| 116 | } else | ||
| 117 | val64 = (u64) val; | ||
| 118 | |||
| 119 | ret = val64; | ||
| 120 | |||
| 121 | bail: | ||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * ipath_qcheck - print delta of egrfull/hdrqfull errors for kernel ports | ||
| 127 | * @dd: the infinipath device | ||
| 128 | * | ||
| 129 | * print the delta of egrfull/hdrqfull errors for kernel ports no more than | ||
| 130 | * every 5 seconds. User processes are printed at close, but kernel doesn't | ||
| 131 | * close, so... Separate routine so may call from other places someday, and | ||
| 132 | * so function name when printed by _IPATH_INFO is meaningfull | ||
| 133 | */ | ||
| 134 | static void ipath_qcheck(struct ipath_devdata *dd) | ||
| 135 | { | ||
| 136 | static u64 last_tot_hdrqfull; | ||
| 137 | size_t blen = 0; | ||
| 138 | char buf[128]; | ||
| 139 | |||
| 140 | *buf = 0; | ||
| 141 | if (dd->ipath_pd[0]->port_hdrqfull != dd->ipath_p0_hdrqfull) { | ||
| 142 | blen = snprintf(buf, sizeof buf, "port 0 hdrqfull %u", | ||
| 143 | dd->ipath_pd[0]->port_hdrqfull - | ||
| 144 | dd->ipath_p0_hdrqfull); | ||
| 145 | dd->ipath_p0_hdrqfull = dd->ipath_pd[0]->port_hdrqfull; | ||
| 146 | } | ||
| 147 | if (ipath_stats.sps_etidfull != dd->ipath_last_tidfull) { | ||
| 148 | blen += snprintf(buf + blen, sizeof buf - blen, | ||
| 149 | "%srcvegrfull %llu", | ||
| 150 | blen ? ", " : "", | ||
| 151 | (unsigned long long) | ||
| 152 | (ipath_stats.sps_etidfull - | ||
| 153 | dd->ipath_last_tidfull)); | ||
| 154 | dd->ipath_last_tidfull = ipath_stats.sps_etidfull; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* | ||
| 158 | * this is actually the number of hdrq full interrupts, not actual | ||
| 159 | * events, but at the moment that's mostly what I'm interested in. | ||
| 160 | * Actual count, etc. is in the counters, if needed. For production | ||
| 161 | * users this won't ordinarily be printed. | ||
| 162 | */ | ||
| 163 | |||
| 164 | if ((ipath_debug & (__IPATH_PKTDBG | __IPATH_DBG)) && | ||
| 165 | ipath_stats.sps_hdrqfull != last_tot_hdrqfull) { | ||
| 166 | blen += snprintf(buf + blen, sizeof buf - blen, | ||
| 167 | "%shdrqfull %llu (all ports)", | ||
| 168 | blen ? ", " : "", | ||
| 169 | (unsigned long long) | ||
| 170 | (ipath_stats.sps_hdrqfull - | ||
| 171 | last_tot_hdrqfull)); | ||
| 172 | last_tot_hdrqfull = ipath_stats.sps_hdrqfull; | ||
| 173 | } | ||
| 174 | if (blen) | ||
| 175 | ipath_dbg("%s\n", buf); | ||
| 176 | |||
| 177 | if (dd->ipath_port0head != (u32) | ||
| 178 | le64_to_cpu(*dd->ipath_hdrqtailptr)) { | ||
| 179 | if (dd->ipath_lastport0rcv_cnt == | ||
| 180 | ipath_stats.sps_port0pkts) { | ||
| 181 | ipath_cdbg(PKT, "missing rcv interrupts? " | ||
| 182 | "port0 hd=%llx tl=%x; port0pkts %llx\n", | ||
| 183 | (unsigned long long) | ||
| 184 | le64_to_cpu(*dd->ipath_hdrqtailptr), | ||
| 185 | dd->ipath_port0head, | ||
| 186 | (unsigned long long) | ||
| 187 | ipath_stats.sps_port0pkts); | ||
| 188 | ipath_kreceive(dd); | ||
| 189 | } | ||
| 190 | dd->ipath_lastport0rcv_cnt = ipath_stats.sps_port0pkts; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * ipath_get_faststats - get word counters from chip before they overflow | ||
| 196 | * @opaque - contains a pointer to the infinipath device ipath_devdata | ||
| 197 | * | ||
| 198 | * called from add_timer | ||
| 199 | */ | ||
| 200 | void ipath_get_faststats(unsigned long opaque) | ||
| 201 | { | ||
| 202 | struct ipath_devdata *dd = (struct ipath_devdata *) opaque; | ||
| 203 | u32 val; | ||
| 204 | static unsigned cnt; | ||
| 205 | |||
| 206 | /* | ||
| 207 | * don't access the chip while running diags, or memory diags can | ||
| 208 | * fail | ||
| 209 | */ | ||
| 210 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT) || | ||
| 211 | ipath_diag_inuse) | ||
| 212 | /* but re-arm the timer, for diags case; won't hurt other */ | ||
| 213 | goto done; | ||
| 214 | |||
| 215 | if (dd->ipath_flags & IPATH_32BITCOUNTERS) { | ||
| 216 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | ||
| 217 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | ||
| 218 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); | ||
| 219 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); | ||
| 220 | } | ||
| 221 | |||
| 222 | ipath_qcheck(dd); | ||
| 223 | |||
| 224 | /* | ||
| 225 | * deal with repeat error suppression. Doesn't really matter if | ||
| 226 | * last error was almost a full interval ago, or just a few usecs | ||
| 227 | * ago; still won't get more than 2 per interval. We may want | ||
| 228 | * longer intervals for this eventually, could do with mod, counter | ||
| 229 | * or separate timer. Also see code in ipath_handle_errors() and | ||
| 230 | * ipath_handle_hwerrors(). | ||
| 231 | */ | ||
| 232 | |||
| 233 | if (dd->ipath_lasterror) | ||
| 234 | dd->ipath_lasterror = 0; | ||
| 235 | if (dd->ipath_lasthwerror) | ||
| 236 | dd->ipath_lasthwerror = 0; | ||
| 237 | if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) | ||
| 238 | && time_after(jiffies, dd->ipath_unmasktime)) { | ||
| 239 | char ebuf[256]; | ||
| 240 | ipath_decode_err(ebuf, sizeof ebuf, | ||
| 241 | (dd->ipath_maskederrs & ~dd-> | ||
| 242 | ipath_ignorederrs)); | ||
| 243 | if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & | ||
| 244 | ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL)) | ||
| 245 | ipath_dev_err(dd, "Re-enabling masked errors " | ||
| 246 | "(%s)\n", ebuf); | ||
| 247 | else { | ||
| 248 | /* | ||
| 249 | * rcvegrfull and rcvhdrqfull are "normal", for some | ||
| 250 | * types of processes (mostly benchmarks) that send | ||
| 251 | * huge numbers of messages, while not processing | ||
| 252 | * them. So only complain about these at debug | ||
| 253 | * level. | ||
| 254 | */ | ||
| 255 | ipath_dbg("Disabling frequent queue full errors " | ||
| 256 | "(%s)\n", ebuf); | ||
| 257 | } | ||
| 258 | dd->ipath_maskederrs = dd->ipath_ignorederrs; | ||
| 259 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
| 260 | ~dd->ipath_maskederrs); | ||
| 261 | } | ||
| 262 | |||
| 263 | /* limit qfull messages to ~one per minute per port */ | ||
| 264 | if ((++cnt & 0x10)) { | ||
| 265 | for (val = dd->ipath_cfgports - 1; ((int)val) >= 0; | ||
| 266 | val--) { | ||
| 267 | if (dd->ipath_lastegrheads[val] != -1) | ||
| 268 | dd->ipath_lastegrheads[val] = -1; | ||
| 269 | if (dd->ipath_lastrcvhdrqtails[val] != -1) | ||
| 270 | dd->ipath_lastrcvhdrqtails[val] = -1; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | if (dd->ipath_nosma_bufs) { | ||
| 275 | dd->ipath_nosma_secs += 5; | ||
| 276 | if (dd->ipath_nosma_secs >= 30) { | ||
| 277 | ipath_cdbg(SMA, "No SMA bufs avail %u seconds; " | ||
| 278 | "cancelling pending sends\n", | ||
| 279 | dd->ipath_nosma_secs); | ||
| 280 | /* | ||
| 281 | * issue an abort as well, in case we have a packet | ||
| 282 | * stuck in launch fifo. This could corrupt an | ||
| 283 | * outgoing user packet in the worst case, | ||
| 284 | * but this is a pretty catastrophic, anyway. | ||
| 285 | */ | ||
| 286 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
| 287 | INFINIPATH_S_ABORT); | ||
| 288 | ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf, | ||
| 289 | dd->ipath_piobcnt2k + | ||
| 290 | dd->ipath_piobcnt4k - | ||
| 291 | dd->ipath_lastport_piobuf); | ||
| 292 | /* start again, if necessary */ | ||
| 293 | dd->ipath_nosma_secs = 0; | ||
| 294 | } else | ||
| 295 | ipath_cdbg(SMA, "No SMA bufs avail %u tries, " | ||
| 296 | "after %u seconds\n", | ||
| 297 | dd->ipath_nosma_bufs, | ||
| 298 | dd->ipath_nosma_secs); | ||
| 299 | } | ||
| 300 | |||
| 301 | done: | ||
| 302 | mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); | ||
| 303 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c new file mode 100644 index 000000000000..32acd8048b49 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
| @@ -0,0 +1,778 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/ctype.h> | ||
| 34 | #include <linux/pci.h> | ||
| 35 | |||
| 36 | #include "ipath_kernel.h" | ||
| 37 | #include "ips_common.h" | ||
| 38 | #include "ipath_layer.h" | ||
| 39 | |||
| 40 | /** | ||
| 41 | * ipath_parse_ushort - parse an unsigned short value in an arbitrary base | ||
| 42 | * @str: the string containing the number | ||
| 43 | * @valp: where to put the result | ||
| 44 | * | ||
| 45 | * returns the number of bytes consumed, or negative value on error | ||
| 46 | */ | ||
| 47 | int ipath_parse_ushort(const char *str, unsigned short *valp) | ||
| 48 | { | ||
| 49 | unsigned long val; | ||
| 50 | char *end; | ||
| 51 | int ret; | ||
| 52 | |||
| 53 | if (!isdigit(str[0])) { | ||
| 54 | ret = -EINVAL; | ||
| 55 | goto bail; | ||
| 56 | } | ||
| 57 | |||
| 58 | val = simple_strtoul(str, &end, 0); | ||
| 59 | |||
| 60 | if (val > 0xffff) { | ||
| 61 | ret = -EINVAL; | ||
| 62 | goto bail; | ||
| 63 | } | ||
| 64 | |||
| 65 | *valp = val; | ||
| 66 | |||
| 67 | ret = end + 1 - str; | ||
| 68 | if (ret == 0) | ||
| 69 | ret = -EINVAL; | ||
| 70 | |||
| 71 | bail: | ||
| 72 | return ret; | ||
| 73 | } | ||
| 74 | |||
| 75 | static ssize_t show_version(struct device_driver *dev, char *buf) | ||
| 76 | { | ||
| 77 | /* The string printed here is already newline-terminated. */ | ||
| 78 | return scnprintf(buf, PAGE_SIZE, "%s", ipath_core_version); | ||
| 79 | } | ||
| 80 | |||
| 81 | static ssize_t show_num_units(struct device_driver *dev, char *buf) | ||
| 82 | { | ||
| 83 | return scnprintf(buf, PAGE_SIZE, "%d\n", | ||
| 84 | ipath_count_units(NULL, NULL, NULL)); | ||
| 85 | } | ||
| 86 | |||
| 87 | #define DRIVER_STAT(name, attr) \ | ||
| 88 | static ssize_t show_stat_##name(struct device_driver *dev, \ | ||
| 89 | char *buf) \ | ||
| 90 | { \ | ||
| 91 | return scnprintf( \ | ||
| 92 | buf, PAGE_SIZE, "%llu\n", \ | ||
| 93 | (unsigned long long) ipath_stats.sps_ ##attr); \ | ||
| 94 | } \ | ||
| 95 | static DRIVER_ATTR(name, S_IRUGO, show_stat_##name, NULL) | ||
| 96 | |||
| 97 | DRIVER_STAT(intrs, ints); | ||
| 98 | DRIVER_STAT(err_intrs, errints); | ||
| 99 | DRIVER_STAT(errs, errs); | ||
| 100 | DRIVER_STAT(pkt_errs, pkterrs); | ||
| 101 | DRIVER_STAT(crc_errs, crcerrs); | ||
| 102 | DRIVER_STAT(hw_errs, hwerrs); | ||
| 103 | DRIVER_STAT(ib_link, iblink); | ||
| 104 | DRIVER_STAT(port0_pkts, port0pkts); | ||
| 105 | DRIVER_STAT(ether_spkts, ether_spkts); | ||
| 106 | DRIVER_STAT(ether_rpkts, ether_rpkts); | ||
| 107 | DRIVER_STAT(sma_spkts, sma_spkts); | ||
| 108 | DRIVER_STAT(sma_rpkts, sma_rpkts); | ||
| 109 | DRIVER_STAT(hdrq_full, hdrqfull); | ||
| 110 | DRIVER_STAT(etid_full, etidfull); | ||
| 111 | DRIVER_STAT(no_piobufs, nopiobufs); | ||
| 112 | DRIVER_STAT(ports, ports); | ||
| 113 | DRIVER_STAT(pkey0, pkeys[0]); | ||
| 114 | DRIVER_STAT(pkey1, pkeys[1]); | ||
| 115 | DRIVER_STAT(pkey2, pkeys[2]); | ||
| 116 | DRIVER_STAT(pkey3, pkeys[3]); | ||
| 117 | /* XXX fix the following when dynamic table of devices used */ | ||
| 118 | DRIVER_STAT(lid0, lid[0]); | ||
| 119 | DRIVER_STAT(lid1, lid[1]); | ||
| 120 | DRIVER_STAT(lid2, lid[2]); | ||
| 121 | DRIVER_STAT(lid3, lid[3]); | ||
| 122 | |||
| 123 | DRIVER_STAT(nports, nports); | ||
| 124 | DRIVER_STAT(null_intr, nullintr); | ||
| 125 | DRIVER_STAT(max_pkts_call, maxpkts_call); | ||
| 126 | DRIVER_STAT(avg_pkts_call, avgpkts_call); | ||
| 127 | DRIVER_STAT(page_locks, pagelocks); | ||
| 128 | DRIVER_STAT(page_unlocks, pageunlocks); | ||
| 129 | DRIVER_STAT(krdrops, krdrops); | ||
| 130 | /* XXX fix the following when dynamic table of devices used */ | ||
| 131 | DRIVER_STAT(mlid0, mlid[0]); | ||
| 132 | DRIVER_STAT(mlid1, mlid[1]); | ||
| 133 | DRIVER_STAT(mlid2, mlid[2]); | ||
| 134 | DRIVER_STAT(mlid3, mlid[3]); | ||
| 135 | |||
| 136 | static struct attribute *driver_stat_attributes[] = { | ||
| 137 | &driver_attr_intrs.attr, | ||
| 138 | &driver_attr_err_intrs.attr, | ||
| 139 | &driver_attr_errs.attr, | ||
| 140 | &driver_attr_pkt_errs.attr, | ||
| 141 | &driver_attr_crc_errs.attr, | ||
| 142 | &driver_attr_hw_errs.attr, | ||
| 143 | &driver_attr_ib_link.attr, | ||
| 144 | &driver_attr_port0_pkts.attr, | ||
| 145 | &driver_attr_ether_spkts.attr, | ||
| 146 | &driver_attr_ether_rpkts.attr, | ||
| 147 | &driver_attr_sma_spkts.attr, | ||
| 148 | &driver_attr_sma_rpkts.attr, | ||
| 149 | &driver_attr_hdrq_full.attr, | ||
| 150 | &driver_attr_etid_full.attr, | ||
| 151 | &driver_attr_no_piobufs.attr, | ||
| 152 | &driver_attr_ports.attr, | ||
| 153 | &driver_attr_pkey0.attr, | ||
| 154 | &driver_attr_pkey1.attr, | ||
| 155 | &driver_attr_pkey2.attr, | ||
| 156 | &driver_attr_pkey3.attr, | ||
| 157 | &driver_attr_lid0.attr, | ||
| 158 | &driver_attr_lid1.attr, | ||
| 159 | &driver_attr_lid2.attr, | ||
| 160 | &driver_attr_lid3.attr, | ||
| 161 | &driver_attr_nports.attr, | ||
| 162 | &driver_attr_null_intr.attr, | ||
| 163 | &driver_attr_max_pkts_call.attr, | ||
| 164 | &driver_attr_avg_pkts_call.attr, | ||
| 165 | &driver_attr_page_locks.attr, | ||
| 166 | &driver_attr_page_unlocks.attr, | ||
| 167 | &driver_attr_krdrops.attr, | ||
| 168 | &driver_attr_mlid0.attr, | ||
| 169 | &driver_attr_mlid1.attr, | ||
| 170 | &driver_attr_mlid2.attr, | ||
| 171 | &driver_attr_mlid3.attr, | ||
| 172 | NULL | ||
| 173 | }; | ||
| 174 | |||
| 175 | static struct attribute_group driver_stat_attr_group = { | ||
| 176 | .name = "stats", | ||
| 177 | .attrs = driver_stat_attributes | ||
| 178 | }; | ||
| 179 | |||
| 180 | static ssize_t show_status(struct device *dev, | ||
| 181 | struct device_attribute *attr, | ||
| 182 | char *buf) | ||
| 183 | { | ||
| 184 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 185 | ssize_t ret; | ||
| 186 | |||
| 187 | if (!dd->ipath_statusp) { | ||
| 188 | ret = -EINVAL; | ||
| 189 | goto bail; | ||
| 190 | } | ||
| 191 | |||
| 192 | ret = scnprintf(buf, PAGE_SIZE, "0x%llx\n", | ||
| 193 | (unsigned long long) *(dd->ipath_statusp)); | ||
| 194 | |||
| 195 | bail: | ||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | static const char *ipath_status_str[] = { | ||
| 200 | "Initted", | ||
| 201 | "Disabled", | ||
| 202 | "Admin_Disabled", | ||
| 203 | "OIB_SMA", | ||
| 204 | "SMA", | ||
| 205 | "Present", | ||
| 206 | "IB_link_up", | ||
| 207 | "IB_configured", | ||
| 208 | "NoIBcable", | ||
| 209 | "Fatal_Hardware_Error", | ||
| 210 | NULL, | ||
| 211 | }; | ||
| 212 | |||
| 213 | static ssize_t show_status_str(struct device *dev, | ||
| 214 | struct device_attribute *attr, | ||
| 215 | char *buf) | ||
| 216 | { | ||
| 217 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 218 | int i, any; | ||
| 219 | u64 s; | ||
| 220 | ssize_t ret; | ||
| 221 | |||
| 222 | if (!dd->ipath_statusp) { | ||
| 223 | ret = -EINVAL; | ||
| 224 | goto bail; | ||
| 225 | } | ||
| 226 | |||
| 227 | s = *(dd->ipath_statusp); | ||
| 228 | *buf = '\0'; | ||
| 229 | for (any = i = 0; s && ipath_status_str[i]; i++) { | ||
| 230 | if (s & 1) { | ||
| 231 | if (any && strlcat(buf, " ", PAGE_SIZE) >= | ||
| 232 | PAGE_SIZE) | ||
| 233 | /* overflow */ | ||
| 234 | break; | ||
| 235 | if (strlcat(buf, ipath_status_str[i], | ||
| 236 | PAGE_SIZE) >= PAGE_SIZE) | ||
| 237 | break; | ||
| 238 | any = 1; | ||
| 239 | } | ||
| 240 | s >>= 1; | ||
| 241 | } | ||
| 242 | if (any) | ||
| 243 | strlcat(buf, "\n", PAGE_SIZE); | ||
| 244 | |||
| 245 | ret = strlen(buf); | ||
| 246 | |||
| 247 | bail: | ||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | |||
| 251 | static ssize_t show_boardversion(struct device *dev, | ||
| 252 | struct device_attribute *attr, | ||
| 253 | char *buf) | ||
| 254 | { | ||
| 255 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 256 | /* The string printed here is already newline-terminated. */ | ||
| 257 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion); | ||
| 258 | } | ||
| 259 | |||
| 260 | static ssize_t show_lid(struct device *dev, | ||
| 261 | struct device_attribute *attr, | ||
| 262 | char *buf) | ||
| 263 | { | ||
| 264 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 265 | |||
| 266 | return scnprintf(buf, PAGE_SIZE, "0x%x\n", dd->ipath_lid); | ||
| 267 | } | ||
| 268 | |||
| 269 | static ssize_t store_lid(struct device *dev, | ||
| 270 | struct device_attribute *attr, | ||
| 271 | const char *buf, | ||
| 272 | size_t count) | ||
| 273 | { | ||
| 274 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 275 | u16 lid; | ||
| 276 | int ret; | ||
| 277 | |||
| 278 | ret = ipath_parse_ushort(buf, &lid); | ||
| 279 | if (ret < 0) | ||
| 280 | goto invalid; | ||
| 281 | |||
| 282 | if (lid == 0 || lid >= 0xc000) { | ||
| 283 | ret = -EINVAL; | ||
| 284 | goto invalid; | ||
| 285 | } | ||
| 286 | |||
| 287 | ipath_set_sps_lid(dd, lid, 0); | ||
| 288 | |||
| 289 | goto bail; | ||
| 290 | invalid: | ||
| 291 | ipath_dev_err(dd, "attempt to set invalid LID\n"); | ||
| 292 | bail: | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | static ssize_t show_mlid(struct device *dev, | ||
| 297 | struct device_attribute *attr, | ||
| 298 | char *buf) | ||
| 299 | { | ||
| 300 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 301 | |||
| 302 | return scnprintf(buf, PAGE_SIZE, "0x%x\n", dd->ipath_mlid); | ||
| 303 | } | ||
| 304 | |||
| 305 | static ssize_t store_mlid(struct device *dev, | ||
| 306 | struct device_attribute *attr, | ||
| 307 | const char *buf, | ||
| 308 | size_t count) | ||
| 309 | { | ||
| 310 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 311 | int unit; | ||
| 312 | u16 mlid; | ||
| 313 | int ret; | ||
| 314 | |||
| 315 | ret = ipath_parse_ushort(buf, &mlid); | ||
| 316 | if (ret < 0) | ||
| 317 | goto invalid; | ||
| 318 | |||
| 319 | unit = dd->ipath_unit; | ||
| 320 | |||
| 321 | dd->ipath_mlid = mlid; | ||
| 322 | ipath_stats.sps_mlid[unit] = mlid; | ||
| 323 | ipath_layer_intr(dd, IPATH_LAYER_INT_BCAST); | ||
| 324 | |||
| 325 | goto bail; | ||
| 326 | invalid: | ||
| 327 | ipath_dev_err(dd, "attempt to set invalid MLID\n"); | ||
| 328 | bail: | ||
| 329 | return ret; | ||
| 330 | } | ||
| 331 | |||
| 332 | static ssize_t show_guid(struct device *dev, | ||
| 333 | struct device_attribute *attr, | ||
| 334 | char *buf) | ||
| 335 | { | ||
| 336 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 337 | u8 *guid; | ||
| 338 | |||
| 339 | guid = (u8 *) & (dd->ipath_guid); | ||
| 340 | |||
| 341 | return scnprintf(buf, PAGE_SIZE, | ||
| 342 | "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 343 | guid[0], guid[1], guid[2], guid[3], | ||
| 344 | guid[4], guid[5], guid[6], guid[7]); | ||
| 345 | } | ||
| 346 | |||
| 347 | static ssize_t store_guid(struct device *dev, | ||
| 348 | struct device_attribute *attr, | ||
| 349 | const char *buf, | ||
| 350 | size_t count) | ||
| 351 | { | ||
| 352 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 353 | ssize_t ret; | ||
| 354 | unsigned short guid[8]; | ||
| 355 | __be64 nguid; | ||
| 356 | u8 *ng; | ||
| 357 | int i; | ||
| 358 | |||
| 359 | if (sscanf(buf, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", | ||
| 360 | &guid[0], &guid[1], &guid[2], &guid[3], | ||
| 361 | &guid[4], &guid[5], &guid[6], &guid[7]) != 8) | ||
| 362 | goto invalid; | ||
| 363 | |||
| 364 | ng = (u8 *) &nguid; | ||
| 365 | |||
| 366 | for (i = 0; i < 8; i++) { | ||
| 367 | if (guid[i] > 0xff) | ||
| 368 | goto invalid; | ||
| 369 | ng[i] = guid[i]; | ||
| 370 | } | ||
| 371 | |||
| 372 | dd->ipath_guid = nguid; | ||
| 373 | dd->ipath_nguid = 1; | ||
| 374 | |||
| 375 | ret = strlen(buf); | ||
| 376 | goto bail; | ||
| 377 | |||
| 378 | invalid: | ||
| 379 | ipath_dev_err(dd, "attempt to set invalid GUID\n"); | ||
| 380 | ret = -EINVAL; | ||
| 381 | |||
| 382 | bail: | ||
| 383 | return ret; | ||
| 384 | } | ||
| 385 | |||
| 386 | static ssize_t show_nguid(struct device *dev, | ||
| 387 | struct device_attribute *attr, | ||
| 388 | char *buf) | ||
| 389 | { | ||
| 390 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 391 | |||
| 392 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_nguid); | ||
| 393 | } | ||
| 394 | |||
| 395 | static ssize_t show_serial(struct device *dev, | ||
| 396 | struct device_attribute *attr, | ||
| 397 | char *buf) | ||
| 398 | { | ||
| 399 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 400 | |||
| 401 | buf[sizeof dd->ipath_serial] = '\0'; | ||
| 402 | memcpy(buf, dd->ipath_serial, sizeof dd->ipath_serial); | ||
| 403 | strcat(buf, "\n"); | ||
| 404 | return strlen(buf); | ||
| 405 | } | ||
| 406 | |||
| 407 | static ssize_t show_unit(struct device *dev, | ||
| 408 | struct device_attribute *attr, | ||
| 409 | char *buf) | ||
| 410 | { | ||
| 411 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 412 | |||
| 413 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit); | ||
| 414 | } | ||
| 415 | |||
| 416 | #define DEVICE_COUNTER(name, attr) \ | ||
| 417 | static ssize_t show_counter_##name(struct device *dev, \ | ||
| 418 | struct device_attribute *attr, \ | ||
| 419 | char *buf) \ | ||
| 420 | { \ | ||
| 421 | struct ipath_devdata *dd = dev_get_drvdata(dev); \ | ||
| 422 | return scnprintf(\ | ||
| 423 | buf, PAGE_SIZE, "%llu\n", (unsigned long long) \ | ||
| 424 | ipath_snap_cntr( \ | ||
| 425 | dd, offsetof(struct infinipath_counters, \ | ||
| 426 | attr) / sizeof(u64))); \ | ||
| 427 | } \ | ||
| 428 | static DEVICE_ATTR(name, S_IRUGO, show_counter_##name, NULL); | ||
| 429 | |||
| 430 | DEVICE_COUNTER(ib_link_downeds, IBLinkDownedCnt); | ||
| 431 | DEVICE_COUNTER(ib_link_err_recoveries, IBLinkErrRecoveryCnt); | ||
| 432 | DEVICE_COUNTER(ib_status_changes, IBStatusChangeCnt); | ||
| 433 | DEVICE_COUNTER(ib_symbol_errs, IBSymbolErrCnt); | ||
| 434 | DEVICE_COUNTER(lb_flow_stalls, LBFlowStallCnt); | ||
| 435 | DEVICE_COUNTER(lb_ints, LBIntCnt); | ||
| 436 | DEVICE_COUNTER(rx_bad_formats, RxBadFormatCnt); | ||
| 437 | DEVICE_COUNTER(rx_buf_ovfls, RxBufOvflCnt); | ||
| 438 | DEVICE_COUNTER(rx_data_pkts, RxDataPktCnt); | ||
| 439 | DEVICE_COUNTER(rx_dropped_pkts, RxDroppedPktCnt); | ||
| 440 | DEVICE_COUNTER(rx_dwords, RxDwordCnt); | ||
| 441 | DEVICE_COUNTER(rx_ebps, RxEBPCnt); | ||
| 442 | DEVICE_COUNTER(rx_flow_ctrl_errs, RxFlowCtrlErrCnt); | ||
| 443 | DEVICE_COUNTER(rx_flow_pkts, RxFlowPktCnt); | ||
| 444 | DEVICE_COUNTER(rx_icrc_errs, RxICRCErrCnt); | ||
| 445 | DEVICE_COUNTER(rx_len_errs, RxLenErrCnt); | ||
| 446 | DEVICE_COUNTER(rx_link_problems, RxLinkProblemCnt); | ||
| 447 | DEVICE_COUNTER(rx_lpcrc_errs, RxLPCRCErrCnt); | ||
| 448 | DEVICE_COUNTER(rx_max_min_len_errs, RxMaxMinLenErrCnt); | ||
| 449 | DEVICE_COUNTER(rx_p0_hdr_egr_ovfls, RxP0HdrEgrOvflCnt); | ||
| 450 | DEVICE_COUNTER(rx_p1_hdr_egr_ovfls, RxP1HdrEgrOvflCnt); | ||
| 451 | DEVICE_COUNTER(rx_p2_hdr_egr_ovfls, RxP2HdrEgrOvflCnt); | ||
| 452 | DEVICE_COUNTER(rx_p3_hdr_egr_ovfls, RxP3HdrEgrOvflCnt); | ||
| 453 | DEVICE_COUNTER(rx_p4_hdr_egr_ovfls, RxP4HdrEgrOvflCnt); | ||
| 454 | DEVICE_COUNTER(rx_p5_hdr_egr_ovfls, RxP5HdrEgrOvflCnt); | ||
| 455 | DEVICE_COUNTER(rx_p6_hdr_egr_ovfls, RxP6HdrEgrOvflCnt); | ||
| 456 | DEVICE_COUNTER(rx_p7_hdr_egr_ovfls, RxP7HdrEgrOvflCnt); | ||
| 457 | DEVICE_COUNTER(rx_p8_hdr_egr_ovfls, RxP8HdrEgrOvflCnt); | ||
| 458 | DEVICE_COUNTER(rx_pkey_mismatches, RxPKeyMismatchCnt); | ||
| 459 | DEVICE_COUNTER(rx_tid_full_errs, RxTIDFullErrCnt); | ||
| 460 | DEVICE_COUNTER(rx_tid_valid_errs, RxTIDValidErrCnt); | ||
| 461 | DEVICE_COUNTER(rx_vcrc_errs, RxVCRCErrCnt); | ||
| 462 | DEVICE_COUNTER(tx_data_pkts, TxDataPktCnt); | ||
| 463 | DEVICE_COUNTER(tx_dropped_pkts, TxDroppedPktCnt); | ||
| 464 | DEVICE_COUNTER(tx_dwords, TxDwordCnt); | ||
| 465 | DEVICE_COUNTER(tx_flow_pkts, TxFlowPktCnt); | ||
| 466 | DEVICE_COUNTER(tx_flow_stalls, TxFlowStallCnt); | ||
| 467 | DEVICE_COUNTER(tx_len_errs, TxLenErrCnt); | ||
| 468 | DEVICE_COUNTER(tx_max_min_len_errs, TxMaxMinLenErrCnt); | ||
| 469 | DEVICE_COUNTER(tx_underruns, TxUnderrunCnt); | ||
| 470 | DEVICE_COUNTER(tx_unsup_vl_errs, TxUnsupVLErrCnt); | ||
| 471 | |||
| 472 | static struct attribute *dev_counter_attributes[] = { | ||
| 473 | &dev_attr_ib_link_downeds.attr, | ||
| 474 | &dev_attr_ib_link_err_recoveries.attr, | ||
| 475 | &dev_attr_ib_status_changes.attr, | ||
| 476 | &dev_attr_ib_symbol_errs.attr, | ||
| 477 | &dev_attr_lb_flow_stalls.attr, | ||
| 478 | &dev_attr_lb_ints.attr, | ||
| 479 | &dev_attr_rx_bad_formats.attr, | ||
| 480 | &dev_attr_rx_buf_ovfls.attr, | ||
| 481 | &dev_attr_rx_data_pkts.attr, | ||
| 482 | &dev_attr_rx_dropped_pkts.attr, | ||
| 483 | &dev_attr_rx_dwords.attr, | ||
| 484 | &dev_attr_rx_ebps.attr, | ||
| 485 | &dev_attr_rx_flow_ctrl_errs.attr, | ||
| 486 | &dev_attr_rx_flow_pkts.attr, | ||
| 487 | &dev_attr_rx_icrc_errs.attr, | ||
| 488 | &dev_attr_rx_len_errs.attr, | ||
| 489 | &dev_attr_rx_link_problems.attr, | ||
| 490 | &dev_attr_rx_lpcrc_errs.attr, | ||
| 491 | &dev_attr_rx_max_min_len_errs.attr, | ||
| 492 | &dev_attr_rx_p0_hdr_egr_ovfls.attr, | ||
| 493 | &dev_attr_rx_p1_hdr_egr_ovfls.attr, | ||
| 494 | &dev_attr_rx_p2_hdr_egr_ovfls.attr, | ||
| 495 | &dev_attr_rx_p3_hdr_egr_ovfls.attr, | ||
| 496 | &dev_attr_rx_p4_hdr_egr_ovfls.attr, | ||
| 497 | &dev_attr_rx_p5_hdr_egr_ovfls.attr, | ||
| 498 | &dev_attr_rx_p6_hdr_egr_ovfls.attr, | ||
| 499 | &dev_attr_rx_p7_hdr_egr_ovfls.attr, | ||
| 500 | &dev_attr_rx_p8_hdr_egr_ovfls.attr, | ||
| 501 | &dev_attr_rx_pkey_mismatches.attr, | ||
| 502 | &dev_attr_rx_tid_full_errs.attr, | ||
| 503 | &dev_attr_rx_tid_valid_errs.attr, | ||
| 504 | &dev_attr_rx_vcrc_errs.attr, | ||
| 505 | &dev_attr_tx_data_pkts.attr, | ||
| 506 | &dev_attr_tx_dropped_pkts.attr, | ||
| 507 | &dev_attr_tx_dwords.attr, | ||
| 508 | &dev_attr_tx_flow_pkts.attr, | ||
| 509 | &dev_attr_tx_flow_stalls.attr, | ||
| 510 | &dev_attr_tx_len_errs.attr, | ||
| 511 | &dev_attr_tx_max_min_len_errs.attr, | ||
| 512 | &dev_attr_tx_underruns.attr, | ||
| 513 | &dev_attr_tx_unsup_vl_errs.attr, | ||
| 514 | NULL | ||
| 515 | }; | ||
| 516 | |||
| 517 | static struct attribute_group dev_counter_attr_group = { | ||
| 518 | .name = "counters", | ||
| 519 | .attrs = dev_counter_attributes | ||
| 520 | }; | ||
| 521 | |||
| 522 | static ssize_t store_reset(struct device *dev, | ||
| 523 | struct device_attribute *attr, | ||
| 524 | const char *buf, | ||
| 525 | size_t count) | ||
| 526 | { | ||
| 527 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 528 | int ret; | ||
| 529 | |||
| 530 | if (count < 5 || memcmp(buf, "reset", 5)) { | ||
| 531 | ret = -EINVAL; | ||
| 532 | goto bail; | ||
| 533 | } | ||
| 534 | |||
| 535 | if (dd->ipath_flags & IPATH_DISABLED) { | ||
| 536 | /* | ||
| 537 | * post-reset init would re-enable interrupts, etc. | ||
| 538 | * so don't allow reset on disabled devices. Not | ||
| 539 | * perfect error, but about the best choice. | ||
| 540 | */ | ||
| 541 | dev_info(dev,"Unit %d is disabled, can't reset\n", | ||
| 542 | dd->ipath_unit); | ||
| 543 | ret = -EINVAL; | ||
| 544 | } | ||
| 545 | ret = ipath_reset_device(dd->ipath_unit); | ||
| 546 | bail: | ||
| 547 | return ret<0 ? ret : count; | ||
| 548 | } | ||
| 549 | |||
| 550 | static ssize_t store_link_state(struct device *dev, | ||
| 551 | struct device_attribute *attr, | ||
| 552 | const char *buf, | ||
| 553 | size_t count) | ||
| 554 | { | ||
| 555 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 556 | int ret, r; | ||
| 557 | u16 state; | ||
| 558 | |||
| 559 | ret = ipath_parse_ushort(buf, &state); | ||
| 560 | if (ret < 0) | ||
| 561 | goto invalid; | ||
| 562 | |||
| 563 | r = ipath_layer_set_linkstate(dd, state); | ||
| 564 | if (r < 0) { | ||
| 565 | ret = r; | ||
| 566 | goto bail; | ||
| 567 | } | ||
| 568 | |||
| 569 | goto bail; | ||
| 570 | invalid: | ||
| 571 | ipath_dev_err(dd, "attempt to set invalid link state\n"); | ||
| 572 | bail: | ||
| 573 | return ret; | ||
| 574 | } | ||
| 575 | |||
| 576 | static ssize_t show_mtu(struct device *dev, | ||
| 577 | struct device_attribute *attr, | ||
| 578 | char *buf) | ||
| 579 | { | ||
| 580 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 581 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_ibmtu); | ||
| 582 | } | ||
| 583 | |||
| 584 | static ssize_t store_mtu(struct device *dev, | ||
| 585 | struct device_attribute *attr, | ||
| 586 | const char *buf, | ||
| 587 | size_t count) | ||
| 588 | { | ||
| 589 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 590 | ssize_t ret; | ||
| 591 | u16 mtu = 0; | ||
| 592 | int r; | ||
| 593 | |||
| 594 | ret = ipath_parse_ushort(buf, &mtu); | ||
| 595 | if (ret < 0) | ||
| 596 | goto invalid; | ||
| 597 | |||
| 598 | r = ipath_layer_set_mtu(dd, mtu); | ||
| 599 | if (r < 0) | ||
| 600 | ret = r; | ||
| 601 | |||
| 602 | goto bail; | ||
| 603 | invalid: | ||
| 604 | ipath_dev_err(dd, "attempt to set invalid MTU\n"); | ||
| 605 | bail: | ||
| 606 | return ret; | ||
| 607 | } | ||
| 608 | |||
| 609 | static ssize_t show_enabled(struct device *dev, | ||
| 610 | struct device_attribute *attr, | ||
| 611 | char *buf) | ||
| 612 | { | ||
| 613 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 614 | return scnprintf(buf, PAGE_SIZE, "%u\n", | ||
| 615 | (dd->ipath_flags & IPATH_DISABLED) ? 0 : 1); | ||
| 616 | } | ||
| 617 | |||
| 618 | static ssize_t store_enabled(struct device *dev, | ||
| 619 | struct device_attribute *attr, | ||
| 620 | const char *buf, | ||
| 621 | size_t count) | ||
| 622 | { | ||
| 623 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 624 | ssize_t ret; | ||
| 625 | u16 enable = 0; | ||
| 626 | |||
| 627 | ret = ipath_parse_ushort(buf, &enable); | ||
| 628 | if (ret < 0) { | ||
| 629 | ipath_dev_err(dd, "attempt to use non-numeric on enable\n"); | ||
| 630 | goto bail; | ||
| 631 | } | ||
| 632 | |||
| 633 | if (enable) { | ||
| 634 | if (!(dd->ipath_flags & IPATH_DISABLED)) | ||
| 635 | goto bail; | ||
| 636 | |||
| 637 | dev_info(dev, "Enabling unit %d\n", dd->ipath_unit); | ||
| 638 | /* same as post-reset */ | ||
| 639 | ret = ipath_init_chip(dd, 1); | ||
| 640 | if (ret) | ||
| 641 | ipath_dev_err(dd, "Failed to enable unit %d\n", | ||
| 642 | dd->ipath_unit); | ||
| 643 | else { | ||
| 644 | dd->ipath_flags &= ~IPATH_DISABLED; | ||
| 645 | *dd->ipath_statusp &= ~IPATH_STATUS_ADMIN_DISABLED; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | else if (!(dd->ipath_flags & IPATH_DISABLED)) { | ||
| 649 | dev_info(dev, "Disabling unit %d\n", dd->ipath_unit); | ||
| 650 | ipath_shutdown_device(dd); | ||
| 651 | dd->ipath_flags |= IPATH_DISABLED; | ||
| 652 | *dd->ipath_statusp |= IPATH_STATUS_ADMIN_DISABLED; | ||
| 653 | } | ||
| 654 | |||
| 655 | bail: | ||
| 656 | return ret; | ||
| 657 | } | ||
| 658 | |||
| 659 | static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); | ||
| 660 | static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); | ||
| 661 | |||
| 662 | static struct attribute *driver_attributes[] = { | ||
| 663 | &driver_attr_num_units.attr, | ||
| 664 | &driver_attr_version.attr, | ||
| 665 | NULL | ||
| 666 | }; | ||
| 667 | |||
| 668 | static struct attribute_group driver_attr_group = { | ||
| 669 | .attrs = driver_attributes | ||
| 670 | }; | ||
| 671 | |||
| 672 | static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid); | ||
| 673 | static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid); | ||
| 674 | static DEVICE_ATTR(link_state, S_IWUSR, NULL, store_link_state); | ||
| 675 | static DEVICE_ATTR(mlid, S_IWUSR | S_IRUGO, show_mlid, store_mlid); | ||
| 676 | static DEVICE_ATTR(mtu, S_IWUSR | S_IRUGO, show_mtu, store_mtu); | ||
| 677 | static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, show_enabled, store_enabled); | ||
| 678 | static DEVICE_ATTR(nguid, S_IRUGO, show_nguid, NULL); | ||
| 679 | static DEVICE_ATTR(reset, S_IWUSR, NULL, store_reset); | ||
| 680 | static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); | ||
| 681 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | ||
| 682 | static DEVICE_ATTR(status_str, S_IRUGO, show_status_str, NULL); | ||
| 683 | static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); | ||
| 684 | static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL); | ||
| 685 | |||
| 686 | static struct attribute *dev_attributes[] = { | ||
| 687 | &dev_attr_guid.attr, | ||
| 688 | &dev_attr_lid.attr, | ||
| 689 | &dev_attr_link_state.attr, | ||
| 690 | &dev_attr_mlid.attr, | ||
| 691 | &dev_attr_mtu.attr, | ||
| 692 | &dev_attr_nguid.attr, | ||
| 693 | &dev_attr_serial.attr, | ||
| 694 | &dev_attr_status.attr, | ||
| 695 | &dev_attr_status_str.attr, | ||
| 696 | &dev_attr_boardversion.attr, | ||
| 697 | &dev_attr_unit.attr, | ||
| 698 | &dev_attr_enabled.attr, | ||
| 699 | NULL | ||
| 700 | }; | ||
| 701 | |||
| 702 | static struct attribute_group dev_attr_group = { | ||
| 703 | .attrs = dev_attributes | ||
| 704 | }; | ||
| 705 | |||
| 706 | /** | ||
| 707 | * ipath_expose_reset - create a device reset file | ||
| 708 | * @dev: the device structure | ||
| 709 | * | ||
| 710 | * Only expose a file that lets us reset the device after someone | ||
| 711 | * enters diag mode. A device reset is quite likely to crash the | ||
| 712 | * machine entirely, so we don't want to normally make it | ||
| 713 | * available. | ||
| 714 | */ | ||
| 715 | int ipath_expose_reset(struct device *dev) | ||
| 716 | { | ||
| 717 | return device_create_file(dev, &dev_attr_reset); | ||
| 718 | } | ||
| 719 | |||
| 720 | int ipath_driver_create_group(struct device_driver *drv) | ||
| 721 | { | ||
| 722 | int ret; | ||
| 723 | |||
| 724 | ret = sysfs_create_group(&drv->kobj, &driver_attr_group); | ||
| 725 | if (ret) | ||
| 726 | goto bail; | ||
| 727 | |||
| 728 | ret = sysfs_create_group(&drv->kobj, &driver_stat_attr_group); | ||
| 729 | if (ret) | ||
| 730 | sysfs_remove_group(&drv->kobj, &driver_attr_group); | ||
| 731 | |||
| 732 | bail: | ||
| 733 | return ret; | ||
| 734 | } | ||
| 735 | |||
| 736 | void ipath_driver_remove_group(struct device_driver *drv) | ||
| 737 | { | ||
| 738 | sysfs_remove_group(&drv->kobj, &driver_stat_attr_group); | ||
| 739 | sysfs_remove_group(&drv->kobj, &driver_attr_group); | ||
| 740 | } | ||
| 741 | |||
| 742 | int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) | ||
| 743 | { | ||
| 744 | int ret; | ||
| 745 | char unit[5]; | ||
| 746 | |||
| 747 | ret = sysfs_create_group(&dev->kobj, &dev_attr_group); | ||
| 748 | if (ret) | ||
| 749 | goto bail; | ||
| 750 | |||
| 751 | ret = sysfs_create_group(&dev->kobj, &dev_counter_attr_group); | ||
| 752 | if (ret) | ||
| 753 | goto bail_attrs; | ||
| 754 | |||
| 755 | snprintf(unit, sizeof(unit), "%02d", dd->ipath_unit); | ||
| 756 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, unit); | ||
| 757 | if (ret == 0) | ||
| 758 | goto bail; | ||
| 759 | |||
| 760 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | ||
| 761 | bail_attrs: | ||
| 762 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | ||
| 763 | bail: | ||
| 764 | return ret; | ||
| 765 | } | ||
| 766 | |||
| 767 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) | ||
| 768 | { | ||
| 769 | char unit[5]; | ||
| 770 | |||
| 771 | snprintf(unit, sizeof(unit), "%02d", dd->ipath_unit); | ||
| 772 | sysfs_remove_link(&dev->driver->kobj, unit); | ||
| 773 | |||
| 774 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | ||
| 775 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | ||
| 776 | |||
| 777 | device_remove_file(dev, &dev_attr_reset); | ||
| 778 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c new file mode 100644 index 000000000000..0d6dbc0a541e --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_uc.c | |||
| @@ -0,0 +1,645 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "ipath_verbs.h" | ||
| 34 | #include "ips_common.h" | ||
| 35 | |||
| 36 | /* cut down ridiculously long IB macro names */ | ||
| 37 | #define OP(x) IB_OPCODE_UC_##x | ||
| 38 | |||
| 39 | static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe, | ||
| 40 | struct ib_wc *wc) | ||
| 41 | { | ||
| 42 | if (++qp->s_last == qp->s_size) | ||
| 43 | qp->s_last = 0; | ||
| 44 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) || | ||
| 45 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
| 46 | wc->wr_id = wqe->wr.wr_id; | ||
| 47 | wc->status = IB_WC_SUCCESS; | ||
| 48 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
| 49 | wc->vendor_err = 0; | ||
| 50 | wc->byte_len = wqe->length; | ||
| 51 | wc->qp_num = qp->ibqp.qp_num; | ||
| 52 | wc->src_qp = qp->remote_qpn; | ||
| 53 | wc->pkey_index = 0; | ||
| 54 | wc->slid = qp->remote_ah_attr.dlid; | ||
| 55 | wc->sl = qp->remote_ah_attr.sl; | ||
| 56 | wc->dlid_path_bits = 0; | ||
| 57 | wc->port_num = 0; | ||
| 58 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 0); | ||
| 59 | } | ||
| 60 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * ipath_do_uc_send - do a send on a UC queue | ||
| 65 | * @data: contains a pointer to the QP to send on | ||
| 66 | * | ||
| 67 | * Process entries in the send work queue until the queue is exhausted. | ||
| 68 | * Only allow one CPU to send a packet per QP (tasklet). | ||
| 69 | * Otherwise, after we drop the QP lock, two threads could send | ||
| 70 | * packets out of order. | ||
| 71 | * This is similar to ipath_do_rc_send() below except we don't have | ||
| 72 | * timeouts or resends. | ||
| 73 | */ | ||
| 74 | void ipath_do_uc_send(unsigned long data) | ||
| 75 | { | ||
| 76 | struct ipath_qp *qp = (struct ipath_qp *)data; | ||
| 77 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 78 | struct ipath_swqe *wqe; | ||
| 79 | unsigned long flags; | ||
| 80 | u16 lrh0; | ||
| 81 | u32 hwords; | ||
| 82 | u32 nwords; | ||
| 83 | u32 extra_bytes; | ||
| 84 | u32 bth0; | ||
| 85 | u32 bth2; | ||
| 86 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
| 87 | u32 len; | ||
| 88 | struct ipath_other_headers *ohdr; | ||
| 89 | struct ib_wc wc; | ||
| 90 | |||
| 91 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags)) | ||
| 92 | goto bail; | ||
| 93 | |||
| 94 | if (unlikely(qp->remote_ah_attr.dlid == | ||
| 95 | ipath_layer_get_lid(dev->dd))) { | ||
| 96 | /* Pass in an uninitialized ib_wc to save stack space. */ | ||
| 97 | ipath_ruc_loopback(qp, &wc); | ||
| 98 | clear_bit(IPATH_S_BUSY, &qp->s_flags); | ||
| 99 | goto bail; | ||
| 100 | } | ||
| 101 | |||
| 102 | ohdr = &qp->s_hdr.u.oth; | ||
| 103 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
| 104 | ohdr = &qp->s_hdr.u.l.oth; | ||
| 105 | |||
| 106 | again: | ||
| 107 | /* Check for a constructed packet to be sent. */ | ||
| 108 | if (qp->s_hdrwords != 0) { | ||
| 109 | /* | ||
| 110 | * If no PIO bufs are available, return. | ||
| 111 | * An interrupt will call ipath_ib_piobufavail() | ||
| 112 | * when one is available. | ||
| 113 | */ | ||
| 114 | if (ipath_verbs_send(dev->dd, qp->s_hdrwords, | ||
| 115 | (u32 *) &qp->s_hdr, | ||
| 116 | qp->s_cur_size, | ||
| 117 | qp->s_cur_sge)) { | ||
| 118 | ipath_no_bufs_available(qp, dev); | ||
| 119 | goto bail; | ||
| 120 | } | ||
| 121 | dev->n_unicast_xmit++; | ||
| 122 | /* Record that we sent the packet and s_hdr is empty. */ | ||
| 123 | qp->s_hdrwords = 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | lrh0 = IPS_LRH_BTH; | ||
| 127 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ | ||
| 128 | hwords = 5; | ||
| 129 | |||
| 130 | /* | ||
| 131 | * The lock is needed to synchronize between | ||
| 132 | * setting qp->s_ack_state and post_send(). | ||
| 133 | */ | ||
| 134 | spin_lock_irqsave(&qp->s_lock, flags); | ||
| 135 | |||
| 136 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) | ||
| 137 | goto done; | ||
| 138 | |||
| 139 | bth0 = ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); | ||
| 140 | |||
| 141 | /* Send a request. */ | ||
| 142 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
| 143 | switch (qp->s_state) { | ||
| 144 | default: | ||
| 145 | /* | ||
| 146 | * Signal the completion of the last send (if there is | ||
| 147 | * one). | ||
| 148 | */ | ||
| 149 | if (qp->s_last != qp->s_tail) | ||
| 150 | complete_last_send(qp, wqe, &wc); | ||
| 151 | |||
| 152 | /* Check if send work queue is empty. */ | ||
| 153 | if (qp->s_tail == qp->s_head) | ||
| 154 | goto done; | ||
| 155 | /* | ||
| 156 | * Start a new request. | ||
| 157 | */ | ||
| 158 | qp->s_psn = wqe->psn = qp->s_next_psn; | ||
| 159 | qp->s_sge.sge = wqe->sg_list[0]; | ||
| 160 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
| 161 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
| 162 | qp->s_len = len = wqe->length; | ||
| 163 | switch (wqe->wr.opcode) { | ||
| 164 | case IB_WR_SEND: | ||
| 165 | case IB_WR_SEND_WITH_IMM: | ||
| 166 | if (len > pmtu) { | ||
| 167 | qp->s_state = OP(SEND_FIRST); | ||
| 168 | len = pmtu; | ||
| 169 | break; | ||
| 170 | } | ||
| 171 | if (wqe->wr.opcode == IB_WR_SEND) | ||
| 172 | qp->s_state = OP(SEND_ONLY); | ||
| 173 | else { | ||
| 174 | qp->s_state = | ||
| 175 | OP(SEND_ONLY_WITH_IMMEDIATE); | ||
| 176 | /* Immediate data comes after the BTH */ | ||
| 177 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 178 | hwords += 1; | ||
| 179 | } | ||
| 180 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 181 | bth0 |= 1 << 23; | ||
| 182 | break; | ||
| 183 | |||
| 184 | case IB_WR_RDMA_WRITE: | ||
| 185 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
| 186 | ohdr->u.rc.reth.vaddr = | ||
| 187 | cpu_to_be64(wqe->wr.wr.rdma.remote_addr); | ||
| 188 | ohdr->u.rc.reth.rkey = | ||
| 189 | cpu_to_be32(wqe->wr.wr.rdma.rkey); | ||
| 190 | ohdr->u.rc.reth.length = cpu_to_be32(len); | ||
| 191 | hwords += sizeof(struct ib_reth) / 4; | ||
| 192 | if (len > pmtu) { | ||
| 193 | qp->s_state = OP(RDMA_WRITE_FIRST); | ||
| 194 | len = pmtu; | ||
| 195 | break; | ||
| 196 | } | ||
| 197 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE) | ||
| 198 | qp->s_state = OP(RDMA_WRITE_ONLY); | ||
| 199 | else { | ||
| 200 | qp->s_state = | ||
| 201 | OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); | ||
| 202 | /* Immediate data comes after the RETH */ | ||
| 203 | ohdr->u.rc.imm_data = wqe->wr.imm_data; | ||
| 204 | hwords += 1; | ||
| 205 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 206 | bth0 |= 1 << 23; | ||
| 207 | } | ||
| 208 | break; | ||
| 209 | |||
| 210 | default: | ||
| 211 | goto done; | ||
| 212 | } | ||
| 213 | if (++qp->s_tail >= qp->s_size) | ||
| 214 | qp->s_tail = 0; | ||
| 215 | break; | ||
| 216 | |||
| 217 | case OP(SEND_FIRST): | ||
| 218 | qp->s_state = OP(SEND_MIDDLE); | ||
| 219 | /* FALLTHROUGH */ | ||
| 220 | case OP(SEND_MIDDLE): | ||
| 221 | len = qp->s_len; | ||
| 222 | if (len > pmtu) { | ||
| 223 | len = pmtu; | ||
| 224 | break; | ||
| 225 | } | ||
| 226 | if (wqe->wr.opcode == IB_WR_SEND) | ||
| 227 | qp->s_state = OP(SEND_LAST); | ||
| 228 | else { | ||
| 229 | qp->s_state = OP(SEND_LAST_WITH_IMMEDIATE); | ||
| 230 | /* Immediate data comes after the BTH */ | ||
| 231 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 232 | hwords += 1; | ||
| 233 | } | ||
| 234 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 235 | bth0 |= 1 << 23; | ||
| 236 | break; | ||
| 237 | |||
| 238 | case OP(RDMA_WRITE_FIRST): | ||
| 239 | qp->s_state = OP(RDMA_WRITE_MIDDLE); | ||
| 240 | /* FALLTHROUGH */ | ||
| 241 | case OP(RDMA_WRITE_MIDDLE): | ||
| 242 | len = qp->s_len; | ||
| 243 | if (len > pmtu) { | ||
| 244 | len = pmtu; | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | if (wqe->wr.opcode == IB_WR_RDMA_WRITE) | ||
| 248 | qp->s_state = OP(RDMA_WRITE_LAST); | ||
| 249 | else { | ||
| 250 | qp->s_state = | ||
| 251 | OP(RDMA_WRITE_LAST_WITH_IMMEDIATE); | ||
| 252 | /* Immediate data comes after the BTH */ | ||
| 253 | ohdr->u.imm_data = wqe->wr.imm_data; | ||
| 254 | hwords += 1; | ||
| 255 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | ||
| 256 | bth0 |= 1 << 23; | ||
| 257 | } | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | bth2 = qp->s_next_psn++ & IPS_PSN_MASK; | ||
| 261 | qp->s_len -= len; | ||
| 262 | bth0 |= qp->s_state << 24; | ||
| 263 | |||
| 264 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 265 | |||
| 266 | /* Construct the header. */ | ||
| 267 | extra_bytes = (4 - len) & 3; | ||
| 268 | nwords = (len + extra_bytes) >> 2; | ||
| 269 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
| 270 | /* Header size in 32-bit words. */ | ||
| 271 | hwords += 10; | ||
| 272 | lrh0 = IPS_LRH_GRH; | ||
| 273 | qp->s_hdr.u.l.grh.version_tclass_flow = | ||
| 274 | cpu_to_be32((6 << 28) | | ||
| 275 | (qp->remote_ah_attr.grh.traffic_class | ||
| 276 | << 20) | | ||
| 277 | qp->remote_ah_attr.grh.flow_label); | ||
| 278 | qp->s_hdr.u.l.grh.paylen = | ||
| 279 | cpu_to_be16(((hwords - 12) + nwords + | ||
| 280 | SIZE_OF_CRC) << 2); | ||
| 281 | /* next_hdr is defined by C8-7 in ch. 8.4.1 */ | ||
| 282 | qp->s_hdr.u.l.grh.next_hdr = 0x1B; | ||
| 283 | qp->s_hdr.u.l.grh.hop_limit = | ||
| 284 | qp->remote_ah_attr.grh.hop_limit; | ||
| 285 | /* The SGID is 32-bit aligned. */ | ||
| 286 | qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = | ||
| 287 | dev->gid_prefix; | ||
| 288 | qp->s_hdr.u.l.grh.sgid.global.interface_id = | ||
| 289 | ipath_layer_get_guid(dev->dd); | ||
| 290 | qp->s_hdr.u.l.grh.dgid = qp->remote_ah_attr.grh.dgid; | ||
| 291 | } | ||
| 292 | qp->s_hdrwords = hwords; | ||
| 293 | qp->s_cur_sge = &qp->s_sge; | ||
| 294 | qp->s_cur_size = len; | ||
| 295 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
| 296 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
| 297 | /* DEST LID */ | ||
| 298 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
| 299 | qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC); | ||
| 300 | qp->s_hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd)); | ||
| 301 | bth0 |= extra_bytes << 20; | ||
| 302 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
| 303 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
| 304 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
| 305 | |||
| 306 | /* Check for more work to do. */ | ||
| 307 | goto again; | ||
| 308 | |||
| 309 | done: | ||
| 310 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 311 | clear_bit(IPATH_S_BUSY, &qp->s_flags); | ||
| 312 | |||
| 313 | bail: | ||
| 314 | return; | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * ipath_uc_rcv - handle an incoming UC packet | ||
| 319 | * @dev: the device the packet came in on | ||
| 320 | * @hdr: the header of the packet | ||
| 321 | * @has_grh: true if the packet has a GRH | ||
| 322 | * @data: the packet data | ||
| 323 | * @tlen: the length of the packet | ||
| 324 | * @qp: the QP for this packet. | ||
| 325 | * | ||
| 326 | * This is called from ipath_qp_rcv() to process an incoming UC packet | ||
| 327 | * for the given QP. | ||
| 328 | * Called at interrupt level. | ||
| 329 | */ | ||
| 330 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 331 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp) | ||
| 332 | { | ||
| 333 | struct ipath_other_headers *ohdr; | ||
| 334 | int opcode; | ||
| 335 | u32 hdrsize; | ||
| 336 | u32 psn; | ||
| 337 | u32 pad; | ||
| 338 | unsigned long flags; | ||
| 339 | struct ib_wc wc; | ||
| 340 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
| 341 | struct ib_reth *reth; | ||
| 342 | int header_in_data; | ||
| 343 | |||
| 344 | /* Check for GRH */ | ||
| 345 | if (!has_grh) { | ||
| 346 | ohdr = &hdr->u.oth; | ||
| 347 | hdrsize = 8 + 12; /* LRH + BTH */ | ||
| 348 | psn = be32_to_cpu(ohdr->bth[2]); | ||
| 349 | header_in_data = 0; | ||
| 350 | } else { | ||
| 351 | ohdr = &hdr->u.l.oth; | ||
| 352 | hdrsize = 8 + 40 + 12; /* LRH + GRH + BTH */ | ||
| 353 | /* | ||
| 354 | * The header with GRH is 60 bytes and the | ||
| 355 | * core driver sets the eager header buffer | ||
| 356 | * size to 56 bytes so the last 4 bytes of | ||
| 357 | * the BTH header (PSN) is in the data buffer. | ||
| 358 | */ | ||
| 359 | header_in_data = | ||
| 360 | ipath_layer_get_rcvhdrentsize(dev->dd) == 16; | ||
| 361 | if (header_in_data) { | ||
| 362 | psn = be32_to_cpu(((__be32 *) data)[0]); | ||
| 363 | data += sizeof(__be32); | ||
| 364 | } else | ||
| 365 | psn = be32_to_cpu(ohdr->bth[2]); | ||
| 366 | } | ||
| 367 | /* | ||
| 368 | * The opcode is in the low byte when its in network order | ||
| 369 | * (top byte when in host order). | ||
| 370 | */ | ||
| 371 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | ||
| 372 | |||
| 373 | wc.imm_data = 0; | ||
| 374 | wc.wc_flags = 0; | ||
| 375 | |||
| 376 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 377 | |||
| 378 | /* Compare the PSN verses the expected PSN. */ | ||
| 379 | if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) { | ||
| 380 | /* | ||
| 381 | * Handle a sequence error. | ||
| 382 | * Silently drop any current message. | ||
| 383 | */ | ||
| 384 | qp->r_psn = psn; | ||
| 385 | inv: | ||
| 386 | qp->r_state = OP(SEND_LAST); | ||
| 387 | switch (opcode) { | ||
| 388 | case OP(SEND_FIRST): | ||
| 389 | case OP(SEND_ONLY): | ||
| 390 | case OP(SEND_ONLY_WITH_IMMEDIATE): | ||
| 391 | goto send_first; | ||
| 392 | |||
| 393 | case OP(RDMA_WRITE_FIRST): | ||
| 394 | case OP(RDMA_WRITE_ONLY): | ||
| 395 | case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): | ||
| 396 | goto rdma_first; | ||
| 397 | |||
| 398 | default: | ||
| 399 | dev->n_pkt_drops++; | ||
| 400 | goto done; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | /* Check for opcode sequence errors. */ | ||
| 405 | switch (qp->r_state) { | ||
| 406 | case OP(SEND_FIRST): | ||
| 407 | case OP(SEND_MIDDLE): | ||
| 408 | if (opcode == OP(SEND_MIDDLE) || | ||
| 409 | opcode == OP(SEND_LAST) || | ||
| 410 | opcode == OP(SEND_LAST_WITH_IMMEDIATE)) | ||
| 411 | break; | ||
| 412 | goto inv; | ||
| 413 | |||
| 414 | case OP(RDMA_WRITE_FIRST): | ||
| 415 | case OP(RDMA_WRITE_MIDDLE): | ||
| 416 | if (opcode == OP(RDMA_WRITE_MIDDLE) || | ||
| 417 | opcode == OP(RDMA_WRITE_LAST) || | ||
| 418 | opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) | ||
| 419 | break; | ||
| 420 | goto inv; | ||
| 421 | |||
| 422 | default: | ||
| 423 | if (opcode == OP(SEND_FIRST) || | ||
| 424 | opcode == OP(SEND_ONLY) || | ||
| 425 | opcode == OP(SEND_ONLY_WITH_IMMEDIATE) || | ||
| 426 | opcode == OP(RDMA_WRITE_FIRST) || | ||
| 427 | opcode == OP(RDMA_WRITE_ONLY) || | ||
| 428 | opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) | ||
| 429 | break; | ||
| 430 | goto inv; | ||
| 431 | } | ||
| 432 | |||
| 433 | /* OK, process the packet. */ | ||
| 434 | switch (opcode) { | ||
| 435 | case OP(SEND_FIRST): | ||
| 436 | case OP(SEND_ONLY): | ||
| 437 | case OP(SEND_ONLY_WITH_IMMEDIATE): | ||
| 438 | send_first: | ||
| 439 | if (qp->r_reuse_sge) { | ||
| 440 | qp->r_reuse_sge = 0; | ||
| 441 | qp->r_sge = qp->s_rdma_sge; | ||
| 442 | } else if (!ipath_get_rwqe(qp, 0)) { | ||
| 443 | dev->n_pkt_drops++; | ||
| 444 | goto done; | ||
| 445 | } | ||
| 446 | /* Save the WQE so we can reuse it in case of an error. */ | ||
| 447 | qp->s_rdma_sge = qp->r_sge; | ||
| 448 | qp->r_rcv_len = 0; | ||
| 449 | if (opcode == OP(SEND_ONLY)) | ||
| 450 | goto send_last; | ||
| 451 | else if (opcode == OP(SEND_ONLY_WITH_IMMEDIATE)) | ||
| 452 | goto send_last_imm; | ||
| 453 | /* FALLTHROUGH */ | ||
| 454 | case OP(SEND_MIDDLE): | ||
| 455 | /* Check for invalid length PMTU or posted rwqe len. */ | ||
| 456 | if (unlikely(tlen != (hdrsize + pmtu + 4))) { | ||
| 457 | qp->r_reuse_sge = 1; | ||
| 458 | dev->n_pkt_drops++; | ||
| 459 | goto done; | ||
| 460 | } | ||
| 461 | qp->r_rcv_len += pmtu; | ||
| 462 | if (unlikely(qp->r_rcv_len > qp->r_len)) { | ||
| 463 | qp->r_reuse_sge = 1; | ||
| 464 | dev->n_pkt_drops++; | ||
| 465 | goto done; | ||
| 466 | } | ||
| 467 | ipath_copy_sge(&qp->r_sge, data, pmtu); | ||
| 468 | break; | ||
| 469 | |||
| 470 | case OP(SEND_LAST_WITH_IMMEDIATE): | ||
| 471 | send_last_imm: | ||
| 472 | if (header_in_data) { | ||
| 473 | wc.imm_data = *(__be32 *) data; | ||
| 474 | data += sizeof(__be32); | ||
| 475 | } else { | ||
| 476 | /* Immediate data comes after BTH */ | ||
| 477 | wc.imm_data = ohdr->u.imm_data; | ||
| 478 | } | ||
| 479 | hdrsize += 4; | ||
| 480 | wc.wc_flags = IB_WC_WITH_IMM; | ||
| 481 | /* FALLTHROUGH */ | ||
| 482 | case OP(SEND_LAST): | ||
| 483 | send_last: | ||
| 484 | /* Get the number of bytes the message was padded by. */ | ||
| 485 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 486 | /* Check for invalid length. */ | ||
| 487 | /* XXX LAST len should be >= 1 */ | ||
| 488 | if (unlikely(tlen < (hdrsize + pad + 4))) { | ||
| 489 | qp->r_reuse_sge = 1; | ||
| 490 | dev->n_pkt_drops++; | ||
| 491 | goto done; | ||
| 492 | } | ||
| 493 | /* Don't count the CRC. */ | ||
| 494 | tlen -= (hdrsize + pad + 4); | ||
| 495 | wc.byte_len = tlen + qp->r_rcv_len; | ||
| 496 | if (unlikely(wc.byte_len > qp->r_len)) { | ||
| 497 | qp->r_reuse_sge = 1; | ||
| 498 | dev->n_pkt_drops++; | ||
| 499 | goto done; | ||
| 500 | } | ||
| 501 | /* XXX Need to free SGEs */ | ||
| 502 | last_imm: | ||
| 503 | ipath_copy_sge(&qp->r_sge, data, tlen); | ||
| 504 | wc.wr_id = qp->r_wr_id; | ||
| 505 | wc.status = IB_WC_SUCCESS; | ||
| 506 | wc.opcode = IB_WC_RECV; | ||
| 507 | wc.vendor_err = 0; | ||
| 508 | wc.qp_num = qp->ibqp.qp_num; | ||
| 509 | wc.src_qp = qp->remote_qpn; | ||
| 510 | wc.pkey_index = 0; | ||
| 511 | wc.slid = qp->remote_ah_attr.dlid; | ||
| 512 | wc.sl = qp->remote_ah_attr.sl; | ||
| 513 | wc.dlid_path_bits = 0; | ||
| 514 | wc.port_num = 0; | ||
| 515 | /* Signal completion event if the solicited bit is set. */ | ||
| 516 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | ||
| 517 | (ohdr->bth[0] & | ||
| 518 | __constant_cpu_to_be32(1 << 23)) != 0); | ||
| 519 | break; | ||
| 520 | |||
| 521 | case OP(RDMA_WRITE_FIRST): | ||
| 522 | case OP(RDMA_WRITE_ONLY): | ||
| 523 | case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): /* consume RWQE */ | ||
| 524 | rdma_first: | ||
| 525 | /* RETH comes after BTH */ | ||
| 526 | if (!header_in_data) | ||
| 527 | reth = &ohdr->u.rc.reth; | ||
| 528 | else { | ||
| 529 | reth = (struct ib_reth *)data; | ||
| 530 | data += sizeof(*reth); | ||
| 531 | } | ||
| 532 | hdrsize += sizeof(*reth); | ||
| 533 | qp->r_len = be32_to_cpu(reth->length); | ||
| 534 | qp->r_rcv_len = 0; | ||
| 535 | if (qp->r_len != 0) { | ||
| 536 | u32 rkey = be32_to_cpu(reth->rkey); | ||
| 537 | u64 vaddr = be64_to_cpu(reth->vaddr); | ||
| 538 | |||
| 539 | /* Check rkey */ | ||
| 540 | if (unlikely(!ipath_rkey_ok( | ||
| 541 | dev, &qp->r_sge, qp->r_len, | ||
| 542 | vaddr, rkey, | ||
| 543 | IB_ACCESS_REMOTE_WRITE))) { | ||
| 544 | dev->n_pkt_drops++; | ||
| 545 | goto done; | ||
| 546 | } | ||
| 547 | } else { | ||
| 548 | qp->r_sge.sg_list = NULL; | ||
| 549 | qp->r_sge.sge.mr = NULL; | ||
| 550 | qp->r_sge.sge.vaddr = NULL; | ||
| 551 | qp->r_sge.sge.length = 0; | ||
| 552 | qp->r_sge.sge.sge_length = 0; | ||
| 553 | } | ||
| 554 | if (unlikely(!(qp->qp_access_flags & | ||
| 555 | IB_ACCESS_REMOTE_WRITE))) { | ||
| 556 | dev->n_pkt_drops++; | ||
| 557 | goto done; | ||
| 558 | } | ||
| 559 | if (opcode == OP(RDMA_WRITE_ONLY)) | ||
| 560 | goto rdma_last; | ||
| 561 | else if (opcode == | ||
| 562 | OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) | ||
| 563 | goto rdma_last_imm; | ||
| 564 | /* FALLTHROUGH */ | ||
| 565 | case OP(RDMA_WRITE_MIDDLE): | ||
| 566 | /* Check for invalid length PMTU or posted rwqe len. */ | ||
| 567 | if (unlikely(tlen != (hdrsize + pmtu + 4))) { | ||
| 568 | dev->n_pkt_drops++; | ||
| 569 | goto done; | ||
| 570 | } | ||
| 571 | qp->r_rcv_len += pmtu; | ||
| 572 | if (unlikely(qp->r_rcv_len > qp->r_len)) { | ||
| 573 | dev->n_pkt_drops++; | ||
| 574 | goto done; | ||
| 575 | } | ||
| 576 | ipath_copy_sge(&qp->r_sge, data, pmtu); | ||
| 577 | break; | ||
| 578 | |||
| 579 | case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): | ||
| 580 | rdma_last_imm: | ||
| 581 | /* Get the number of bytes the message was padded by. */ | ||
| 582 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 583 | /* Check for invalid length. */ | ||
| 584 | /* XXX LAST len should be >= 1 */ | ||
| 585 | if (unlikely(tlen < (hdrsize + pad + 4))) { | ||
| 586 | dev->n_pkt_drops++; | ||
| 587 | goto done; | ||
| 588 | } | ||
| 589 | /* Don't count the CRC. */ | ||
| 590 | tlen -= (hdrsize + pad + 4); | ||
| 591 | if (unlikely(tlen + qp->r_rcv_len != qp->r_len)) { | ||
| 592 | dev->n_pkt_drops++; | ||
| 593 | goto done; | ||
| 594 | } | ||
| 595 | if (qp->r_reuse_sge) { | ||
| 596 | qp->r_reuse_sge = 0; | ||
| 597 | } else if (!ipath_get_rwqe(qp, 1)) { | ||
| 598 | dev->n_pkt_drops++; | ||
| 599 | goto done; | ||
| 600 | } | ||
| 601 | if (header_in_data) { | ||
| 602 | wc.imm_data = *(__be32 *) data; | ||
| 603 | data += sizeof(__be32); | ||
| 604 | } else { | ||
| 605 | /* Immediate data comes after BTH */ | ||
| 606 | wc.imm_data = ohdr->u.imm_data; | ||
| 607 | } | ||
| 608 | hdrsize += 4; | ||
| 609 | wc.wc_flags = IB_WC_WITH_IMM; | ||
| 610 | wc.byte_len = 0; | ||
| 611 | goto last_imm; | ||
| 612 | |||
| 613 | case OP(RDMA_WRITE_LAST): | ||
| 614 | rdma_last: | ||
| 615 | /* Get the number of bytes the message was padded by. */ | ||
| 616 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 617 | /* Check for invalid length. */ | ||
| 618 | /* XXX LAST len should be >= 1 */ | ||
| 619 | if (unlikely(tlen < (hdrsize + pad + 4))) { | ||
| 620 | dev->n_pkt_drops++; | ||
| 621 | goto done; | ||
| 622 | } | ||
| 623 | /* Don't count the CRC. */ | ||
| 624 | tlen -= (hdrsize + pad + 4); | ||
| 625 | if (unlikely(tlen + qp->r_rcv_len != qp->r_len)) { | ||
| 626 | dev->n_pkt_drops++; | ||
| 627 | goto done; | ||
| 628 | } | ||
| 629 | ipath_copy_sge(&qp->r_sge, data, tlen); | ||
| 630 | break; | ||
| 631 | |||
| 632 | default: | ||
| 633 | /* Drop packet for unknown opcodes. */ | ||
| 634 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 635 | dev->n_pkt_drops++; | ||
| 636 | goto bail; | ||
| 637 | } | ||
| 638 | qp->r_psn++; | ||
| 639 | qp->r_state = opcode; | ||
| 640 | done: | ||
| 641 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 642 | |||
| 643 | bail: | ||
| 644 | return; | ||
| 645 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c new file mode 100644 index 000000000000..5ff3de6128b2 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
| @@ -0,0 +1,621 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <rdma/ib_smi.h> | ||
| 34 | |||
| 35 | #include "ipath_verbs.h" | ||
| 36 | #include "ips_common.h" | ||
| 37 | |||
| 38 | /** | ||
| 39 | * ipath_ud_loopback - handle send on loopback QPs | ||
| 40 | * @sqp: the QP | ||
| 41 | * @ss: the SGE state | ||
| 42 | * @length: the length of the data to send | ||
| 43 | * @wr: the work request | ||
| 44 | * @wc: the work completion entry | ||
| 45 | * | ||
| 46 | * This is called from ipath_post_ud_send() to forward a WQE addressed | ||
| 47 | * to the same HCA. | ||
| 48 | */ | ||
| 49 | void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, | ||
| 50 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc) | ||
| 51 | { | ||
| 52 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | ||
| 53 | struct ipath_qp *qp; | ||
| 54 | struct ib_ah_attr *ah_attr; | ||
| 55 | unsigned long flags; | ||
| 56 | struct ipath_rq *rq; | ||
| 57 | struct ipath_srq *srq; | ||
| 58 | struct ipath_sge_state rsge; | ||
| 59 | struct ipath_sge *sge; | ||
| 60 | struct ipath_rwqe *wqe; | ||
| 61 | |||
| 62 | qp = ipath_lookup_qpn(&dev->qp_table, wr->wr.ud.remote_qpn); | ||
| 63 | if (!qp) | ||
| 64 | return; | ||
| 65 | |||
| 66 | /* | ||
| 67 | * Check that the qkey matches (except for QP0, see 9.6.1.4.1). | ||
| 68 | * Qkeys with the high order bit set mean use the | ||
| 69 | * qkey from the QP context instead of the WR (see 10.2.5). | ||
| 70 | */ | ||
| 71 | if (unlikely(qp->ibqp.qp_num && | ||
| 72 | ((int) wr->wr.ud.remote_qkey < 0 | ||
| 73 | ? qp->qkey : wr->wr.ud.remote_qkey) != qp->qkey)) { | ||
| 74 | /* XXX OK to lose a count once in a while. */ | ||
| 75 | dev->qkey_violations++; | ||
| 76 | dev->n_pkt_drops++; | ||
| 77 | goto done; | ||
| 78 | } | ||
| 79 | |||
| 80 | /* | ||
| 81 | * A GRH is expected to preceed the data even if not | ||
| 82 | * present on the wire. | ||
| 83 | */ | ||
| 84 | wc->byte_len = length + sizeof(struct ib_grh); | ||
| 85 | |||
| 86 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | ||
| 87 | wc->wc_flags = IB_WC_WITH_IMM; | ||
| 88 | wc->imm_data = wr->imm_data; | ||
| 89 | } else { | ||
| 90 | wc->wc_flags = 0; | ||
| 91 | wc->imm_data = 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Get the next work request entry to find where to put the data. | ||
| 96 | * Note that it is safe to drop the lock after changing rq->tail | ||
| 97 | * since ipath_post_receive() won't fill the empty slot. | ||
| 98 | */ | ||
| 99 | if (qp->ibqp.srq) { | ||
| 100 | srq = to_isrq(qp->ibqp.srq); | ||
| 101 | rq = &srq->rq; | ||
| 102 | } else { | ||
| 103 | srq = NULL; | ||
| 104 | rq = &qp->r_rq; | ||
| 105 | } | ||
| 106 | spin_lock_irqsave(&rq->lock, flags); | ||
| 107 | if (rq->tail == rq->head) { | ||
| 108 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 109 | dev->n_pkt_drops++; | ||
| 110 | goto done; | ||
| 111 | } | ||
| 112 | /* Silently drop packets which are too big. */ | ||
| 113 | wqe = get_rwqe_ptr(rq, rq->tail); | ||
| 114 | if (wc->byte_len > wqe->length) { | ||
| 115 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 116 | dev->n_pkt_drops++; | ||
| 117 | goto done; | ||
| 118 | } | ||
| 119 | wc->wr_id = wqe->wr_id; | ||
| 120 | rsge.sge = wqe->sg_list[0]; | ||
| 121 | rsge.sg_list = wqe->sg_list + 1; | ||
| 122 | rsge.num_sge = wqe->num_sge; | ||
| 123 | if (++rq->tail >= rq->size) | ||
| 124 | rq->tail = 0; | ||
| 125 | if (srq && srq->ibsrq.event_handler) { | ||
| 126 | u32 n; | ||
| 127 | |||
| 128 | if (rq->head < rq->tail) | ||
| 129 | n = rq->size + rq->head - rq->tail; | ||
| 130 | else | ||
| 131 | n = rq->head - rq->tail; | ||
| 132 | if (n < srq->limit) { | ||
| 133 | struct ib_event ev; | ||
| 134 | |||
| 135 | srq->limit = 0; | ||
| 136 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 137 | ev.device = qp->ibqp.device; | ||
| 138 | ev.element.srq = qp->ibqp.srq; | ||
| 139 | ev.event = IB_EVENT_SRQ_LIMIT_REACHED; | ||
| 140 | srq->ibsrq.event_handler(&ev, | ||
| 141 | srq->ibsrq.srq_context); | ||
| 142 | } else | ||
| 143 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 144 | } else | ||
| 145 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 146 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | ||
| 147 | if (ah_attr->ah_flags & IB_AH_GRH) { | ||
| 148 | ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); | ||
| 149 | wc->wc_flags |= IB_WC_GRH; | ||
| 150 | } else | ||
| 151 | ipath_skip_sge(&rsge, sizeof(struct ib_grh)); | ||
| 152 | sge = &ss->sge; | ||
| 153 | while (length) { | ||
| 154 | u32 len = sge->length; | ||
| 155 | |||
| 156 | if (len > length) | ||
| 157 | len = length; | ||
| 158 | BUG_ON(len == 0); | ||
| 159 | ipath_copy_sge(&rsge, sge->vaddr, len); | ||
| 160 | sge->vaddr += len; | ||
| 161 | sge->length -= len; | ||
| 162 | sge->sge_length -= len; | ||
| 163 | if (sge->sge_length == 0) { | ||
| 164 | if (--ss->num_sge) | ||
| 165 | *sge = *ss->sg_list++; | ||
| 166 | } else if (sge->length == 0 && sge->mr != NULL) { | ||
| 167 | if (++sge->n >= IPATH_SEGSZ) { | ||
| 168 | if (++sge->m >= sge->mr->mapsz) | ||
| 169 | break; | ||
| 170 | sge->n = 0; | ||
| 171 | } | ||
| 172 | sge->vaddr = | ||
| 173 | sge->mr->map[sge->m]->segs[sge->n].vaddr; | ||
| 174 | sge->length = | ||
| 175 | sge->mr->map[sge->m]->segs[sge->n].length; | ||
| 176 | } | ||
| 177 | length -= len; | ||
| 178 | } | ||
| 179 | wc->status = IB_WC_SUCCESS; | ||
| 180 | wc->opcode = IB_WC_RECV; | ||
| 181 | wc->vendor_err = 0; | ||
| 182 | wc->qp_num = qp->ibqp.qp_num; | ||
| 183 | wc->src_qp = sqp->ibqp.qp_num; | ||
| 184 | /* XXX do we know which pkey matched? Only needed for GSI. */ | ||
| 185 | wc->pkey_index = 0; | ||
| 186 | wc->slid = ipath_layer_get_lid(dev->dd) | | ||
| 187 | (ah_attr->src_path_bits & | ||
| 188 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1)); | ||
| 189 | wc->sl = ah_attr->sl; | ||
| 190 | wc->dlid_path_bits = | ||
| 191 | ah_attr->dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | ||
| 192 | /* Signal completion event if the solicited bit is set. */ | ||
| 193 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc, | ||
| 194 | wr->send_flags & IB_SEND_SOLICITED); | ||
| 195 | |||
| 196 | done: | ||
| 197 | if (atomic_dec_and_test(&qp->refcount)) | ||
| 198 | wake_up(&qp->wait); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * ipath_post_ud_send - post a UD send on QP | ||
| 203 | * @qp: the QP | ||
| 204 | * @wr: the work request | ||
| 205 | * | ||
| 206 | * Note that we actually send the data as it is posted instead of putting | ||
| 207 | * the request into a ring buffer. If we wanted to use a ring buffer, | ||
| 208 | * we would need to save a reference to the destination address in the SWQE. | ||
| 209 | */ | ||
| 210 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
| 211 | { | ||
| 212 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
| 213 | struct ipath_other_headers *ohdr; | ||
| 214 | struct ib_ah_attr *ah_attr; | ||
| 215 | struct ipath_sge_state ss; | ||
| 216 | struct ipath_sge *sg_list; | ||
| 217 | struct ib_wc wc; | ||
| 218 | u32 hwords; | ||
| 219 | u32 nwords; | ||
| 220 | u32 len; | ||
| 221 | u32 extra_bytes; | ||
| 222 | u32 bth0; | ||
| 223 | u16 lrh0; | ||
| 224 | u16 lid; | ||
| 225 | int i; | ||
| 226 | int ret; | ||
| 227 | |||
| 228 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) { | ||
| 229 | ret = 0; | ||
| 230 | goto bail; | ||
| 231 | } | ||
| 232 | |||
| 233 | /* IB spec says that num_sge == 0 is OK. */ | ||
| 234 | if (wr->num_sge > qp->s_max_sge) { | ||
| 235 | ret = -EINVAL; | ||
| 236 | goto bail; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (wr->num_sge > 1) { | ||
| 240 | sg_list = kmalloc((qp->s_max_sge - 1) * sizeof(*sg_list), | ||
| 241 | GFP_ATOMIC); | ||
| 242 | if (!sg_list) { | ||
| 243 | ret = -ENOMEM; | ||
| 244 | goto bail; | ||
| 245 | } | ||
| 246 | } else | ||
| 247 | sg_list = NULL; | ||
| 248 | |||
| 249 | /* Check the buffer to send. */ | ||
| 250 | ss.sg_list = sg_list; | ||
| 251 | ss.sge.mr = NULL; | ||
| 252 | ss.sge.vaddr = NULL; | ||
| 253 | ss.sge.length = 0; | ||
| 254 | ss.sge.sge_length = 0; | ||
| 255 | ss.num_sge = 0; | ||
| 256 | len = 0; | ||
| 257 | for (i = 0; i < wr->num_sge; i++) { | ||
| 258 | /* Check LKEY */ | ||
| 259 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
| 260 | ret = -EINVAL; | ||
| 261 | goto bail; | ||
| 262 | } | ||
| 263 | |||
| 264 | if (wr->sg_list[i].length == 0) | ||
| 265 | continue; | ||
| 266 | if (!ipath_lkey_ok(&dev->lk_table, ss.num_sge ? | ||
| 267 | sg_list + ss.num_sge - 1 : &ss.sge, | ||
| 268 | &wr->sg_list[i], 0)) { | ||
| 269 | ret = -EINVAL; | ||
| 270 | goto bail; | ||
| 271 | } | ||
| 272 | len += wr->sg_list[i].length; | ||
| 273 | ss.num_sge++; | ||
| 274 | } | ||
| 275 | extra_bytes = (4 - len) & 3; | ||
| 276 | nwords = (len + extra_bytes) >> 2; | ||
| 277 | |||
| 278 | /* Construct the header. */ | ||
| 279 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | ||
| 280 | if (ah_attr->dlid == 0) { | ||
| 281 | ret = -EINVAL; | ||
| 282 | goto bail; | ||
| 283 | } | ||
| 284 | if (ah_attr->dlid >= IPS_MULTICAST_LID_BASE) { | ||
| 285 | if (ah_attr->dlid != IPS_PERMISSIVE_LID) | ||
| 286 | dev->n_multicast_xmit++; | ||
| 287 | else | ||
| 288 | dev->n_unicast_xmit++; | ||
| 289 | } else { | ||
| 290 | dev->n_unicast_xmit++; | ||
| 291 | lid = ah_attr->dlid & | ||
| 292 | ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | ||
| 293 | if (unlikely(lid == ipath_layer_get_lid(dev->dd))) { | ||
| 294 | /* | ||
| 295 | * Pass in an uninitialized ib_wc to save stack | ||
| 296 | * space. | ||
| 297 | */ | ||
| 298 | ipath_ud_loopback(qp, &ss, len, wr, &wc); | ||
| 299 | goto done; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | if (ah_attr->ah_flags & IB_AH_GRH) { | ||
| 303 | /* Header size in 32-bit words. */ | ||
| 304 | hwords = 17; | ||
| 305 | lrh0 = IPS_LRH_GRH; | ||
| 306 | ohdr = &qp->s_hdr.u.l.oth; | ||
| 307 | qp->s_hdr.u.l.grh.version_tclass_flow = | ||
| 308 | cpu_to_be32((6 << 28) | | ||
| 309 | (ah_attr->grh.traffic_class << 20) | | ||
| 310 | ah_attr->grh.flow_label); | ||
| 311 | qp->s_hdr.u.l.grh.paylen = | ||
| 312 | cpu_to_be16(((wr->opcode == | ||
| 313 | IB_WR_SEND_WITH_IMM ? 6 : 5) + | ||
| 314 | nwords + SIZE_OF_CRC) << 2); | ||
| 315 | /* next_hdr is defined by C8-7 in ch. 8.4.1 */ | ||
| 316 | qp->s_hdr.u.l.grh.next_hdr = 0x1B; | ||
| 317 | qp->s_hdr.u.l.grh.hop_limit = ah_attr->grh.hop_limit; | ||
| 318 | /* The SGID is 32-bit aligned. */ | ||
| 319 | qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = | ||
| 320 | dev->gid_prefix; | ||
| 321 | qp->s_hdr.u.l.grh.sgid.global.interface_id = | ||
| 322 | ipath_layer_get_guid(dev->dd); | ||
| 323 | qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid; | ||
| 324 | /* | ||
| 325 | * Don't worry about sending to locally attached multicast | ||
| 326 | * QPs. It is unspecified by the spec. what happens. | ||
| 327 | */ | ||
| 328 | } else { | ||
| 329 | /* Header size in 32-bit words. */ | ||
| 330 | hwords = 7; | ||
| 331 | lrh0 = IPS_LRH_BTH; | ||
| 332 | ohdr = &qp->s_hdr.u.oth; | ||
| 333 | } | ||
| 334 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | ||
| 335 | ohdr->u.ud.imm_data = wr->imm_data; | ||
| 336 | wc.imm_data = wr->imm_data; | ||
| 337 | hwords += 1; | ||
| 338 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; | ||
| 339 | } else if (wr->opcode == IB_WR_SEND) { | ||
| 340 | wc.imm_data = 0; | ||
| 341 | bth0 = IB_OPCODE_UD_SEND_ONLY << 24; | ||
| 342 | } else { | ||
| 343 | ret = -EINVAL; | ||
| 344 | goto bail; | ||
| 345 | } | ||
| 346 | lrh0 |= ah_attr->sl << 4; | ||
| 347 | if (qp->ibqp.qp_type == IB_QPT_SMI) | ||
| 348 | lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ | ||
| 349 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
| 350 | qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ | ||
| 351 | qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC); | ||
| 352 | lid = ipath_layer_get_lid(dev->dd); | ||
| 353 | if (lid) { | ||
| 354 | lid |= ah_attr->src_path_bits & | ||
| 355 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | ||
| 356 | qp->s_hdr.lrh[3] = cpu_to_be16(lid); | ||
| 357 | } else | ||
| 358 | qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; | ||
| 359 | if (wr->send_flags & IB_SEND_SOLICITED) | ||
| 360 | bth0 |= 1 << 23; | ||
| 361 | bth0 |= extra_bytes << 20; | ||
| 362 | bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPS_DEFAULT_P_KEY : | ||
| 363 | ipath_layer_get_pkey(dev->dd, qp->s_pkey_index); | ||
| 364 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
| 365 | /* | ||
| 366 | * Use the multicast QP if the destination LID is a multicast LID. | ||
| 367 | */ | ||
| 368 | ohdr->bth[1] = ah_attr->dlid >= IPS_MULTICAST_LID_BASE && | ||
| 369 | ah_attr->dlid != IPS_PERMISSIVE_LID ? | ||
| 370 | __constant_cpu_to_be32(IPS_MULTICAST_QPN) : | ||
| 371 | cpu_to_be32(wr->wr.ud.remote_qpn); | ||
| 372 | /* XXX Could lose a PSN count but not worth locking */ | ||
| 373 | ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPS_PSN_MASK); | ||
| 374 | /* | ||
| 375 | * Qkeys with the high order bit set mean use the | ||
| 376 | * qkey from the QP context instead of the WR (see 10.2.5). | ||
| 377 | */ | ||
| 378 | ohdr->u.ud.deth[0] = cpu_to_be32((int)wr->wr.ud.remote_qkey < 0 ? | ||
| 379 | qp->qkey : wr->wr.ud.remote_qkey); | ||
| 380 | ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); | ||
| 381 | if (ipath_verbs_send(dev->dd, hwords, (u32 *) &qp->s_hdr, | ||
| 382 | len, &ss)) | ||
| 383 | dev->n_no_piobuf++; | ||
| 384 | |||
| 385 | done: | ||
| 386 | /* Queue the completion status entry. */ | ||
| 387 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) || | ||
| 388 | (wr->send_flags & IB_SEND_SIGNALED)) { | ||
| 389 | wc.wr_id = wr->wr_id; | ||
| 390 | wc.status = IB_WC_SUCCESS; | ||
| 391 | wc.vendor_err = 0; | ||
| 392 | wc.opcode = IB_WC_SEND; | ||
| 393 | wc.byte_len = len; | ||
| 394 | wc.qp_num = qp->ibqp.qp_num; | ||
| 395 | wc.src_qp = 0; | ||
| 396 | wc.wc_flags = 0; | ||
| 397 | /* XXX initialize other fields? */ | ||
| 398 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
| 399 | } | ||
| 400 | kfree(sg_list); | ||
| 401 | |||
| 402 | ret = 0; | ||
| 403 | |||
| 404 | bail: | ||
| 405 | return ret; | ||
| 406 | } | ||
| 407 | |||
| 408 | /** | ||
| 409 | * ipath_ud_rcv - receive an incoming UD packet | ||
| 410 | * @dev: the device the packet came in on | ||
| 411 | * @hdr: the packet header | ||
| 412 | * @has_grh: true if the packet has a GRH | ||
| 413 | * @data: the packet data | ||
| 414 | * @tlen: the packet length | ||
| 415 | * @qp: the QP the packet came on | ||
| 416 | * | ||
| 417 | * This is called from ipath_qp_rcv() to process an incoming UD packet | ||
| 418 | * for the given QP. | ||
| 419 | * Called at interrupt level. | ||
| 420 | */ | ||
| 421 | void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 422 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp) | ||
| 423 | { | ||
| 424 | struct ipath_other_headers *ohdr; | ||
| 425 | int opcode; | ||
| 426 | u32 hdrsize; | ||
| 427 | u32 pad; | ||
| 428 | unsigned long flags; | ||
| 429 | struct ib_wc wc; | ||
| 430 | u32 qkey; | ||
| 431 | u32 src_qp; | ||
| 432 | struct ipath_rq *rq; | ||
| 433 | struct ipath_srq *srq; | ||
| 434 | struct ipath_rwqe *wqe; | ||
| 435 | u16 dlid; | ||
| 436 | int header_in_data; | ||
| 437 | |||
| 438 | /* Check for GRH */ | ||
| 439 | if (!has_grh) { | ||
| 440 | ohdr = &hdr->u.oth; | ||
| 441 | hdrsize = 8 + 12 + 8; /* LRH + BTH + DETH */ | ||
| 442 | qkey = be32_to_cpu(ohdr->u.ud.deth[0]); | ||
| 443 | src_qp = be32_to_cpu(ohdr->u.ud.deth[1]); | ||
| 444 | header_in_data = 0; | ||
| 445 | } else { | ||
| 446 | ohdr = &hdr->u.l.oth; | ||
| 447 | hdrsize = 8 + 40 + 12 + 8; /* LRH + GRH + BTH + DETH */ | ||
| 448 | /* | ||
| 449 | * The header with GRH is 68 bytes and the core driver sets | ||
| 450 | * the eager header buffer size to 56 bytes so the last 12 | ||
| 451 | * bytes of the IB header is in the data buffer. | ||
| 452 | */ | ||
| 453 | header_in_data = | ||
| 454 | ipath_layer_get_rcvhdrentsize(dev->dd) == 16; | ||
| 455 | if (header_in_data) { | ||
| 456 | qkey = be32_to_cpu(((__be32 *) data)[1]); | ||
| 457 | src_qp = be32_to_cpu(((__be32 *) data)[2]); | ||
| 458 | data += 12; | ||
| 459 | } else { | ||
| 460 | qkey = be32_to_cpu(ohdr->u.ud.deth[0]); | ||
| 461 | src_qp = be32_to_cpu(ohdr->u.ud.deth[1]); | ||
| 462 | } | ||
| 463 | } | ||
| 464 | src_qp &= IPS_QPN_MASK; | ||
| 465 | |||
| 466 | /* | ||
| 467 | * Check that the permissive LID is only used on QP0 | ||
| 468 | * and the QKEY matches (see 9.6.1.4.1 and 9.6.1.5.1). | ||
| 469 | */ | ||
| 470 | if (qp->ibqp.qp_num) { | ||
| 471 | if (unlikely(hdr->lrh[1] == IB_LID_PERMISSIVE || | ||
| 472 | hdr->lrh[3] == IB_LID_PERMISSIVE)) { | ||
| 473 | dev->n_pkt_drops++; | ||
| 474 | goto bail; | ||
| 475 | } | ||
| 476 | if (unlikely(qkey != qp->qkey)) { | ||
| 477 | /* XXX OK to lose a count once in a while. */ | ||
| 478 | dev->qkey_violations++; | ||
| 479 | dev->n_pkt_drops++; | ||
| 480 | goto bail; | ||
| 481 | } | ||
| 482 | } else if (hdr->lrh[1] == IB_LID_PERMISSIVE || | ||
| 483 | hdr->lrh[3] == IB_LID_PERMISSIVE) { | ||
| 484 | struct ib_smp *smp = (struct ib_smp *) data; | ||
| 485 | |||
| 486 | if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { | ||
| 487 | dev->n_pkt_drops++; | ||
| 488 | goto bail; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | /* Get the number of bytes the message was padded by. */ | ||
| 493 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | ||
| 494 | if (unlikely(tlen < (hdrsize + pad + 4))) { | ||
| 495 | /* Drop incomplete packets. */ | ||
| 496 | dev->n_pkt_drops++; | ||
| 497 | goto bail; | ||
| 498 | } | ||
| 499 | tlen -= hdrsize + pad + 4; | ||
| 500 | |||
| 501 | /* Drop invalid MAD packets (see 13.5.3.1). */ | ||
| 502 | if (unlikely((qp->ibqp.qp_num == 0 && | ||
| 503 | (tlen != 256 || | ||
| 504 | (be16_to_cpu(hdr->lrh[0]) >> 12) != 15)) || | ||
| 505 | (qp->ibqp.qp_num == 1 && | ||
| 506 | (tlen != 256 || | ||
| 507 | (be16_to_cpu(hdr->lrh[0]) >> 12) == 15)))) { | ||
| 508 | dev->n_pkt_drops++; | ||
| 509 | goto bail; | ||
| 510 | } | ||
| 511 | |||
| 512 | /* | ||
| 513 | * A GRH is expected to preceed the data even if not | ||
| 514 | * present on the wire. | ||
| 515 | */ | ||
| 516 | wc.byte_len = tlen + sizeof(struct ib_grh); | ||
| 517 | |||
| 518 | /* | ||
| 519 | * The opcode is in the low byte when its in network order | ||
| 520 | * (top byte when in host order). | ||
| 521 | */ | ||
| 522 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | ||
| 523 | if (qp->ibqp.qp_num > 1 && | ||
| 524 | opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { | ||
| 525 | if (header_in_data) { | ||
| 526 | wc.imm_data = *(__be32 *) data; | ||
| 527 | data += sizeof(__be32); | ||
| 528 | } else | ||
| 529 | wc.imm_data = ohdr->u.ud.imm_data; | ||
| 530 | wc.wc_flags = IB_WC_WITH_IMM; | ||
| 531 | hdrsize += sizeof(u32); | ||
| 532 | } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { | ||
| 533 | wc.imm_data = 0; | ||
| 534 | wc.wc_flags = 0; | ||
| 535 | } else { | ||
| 536 | dev->n_pkt_drops++; | ||
| 537 | goto bail; | ||
| 538 | } | ||
| 539 | |||
| 540 | /* | ||
| 541 | * Get the next work request entry to find where to put the data. | ||
| 542 | * Note that it is safe to drop the lock after changing rq->tail | ||
| 543 | * since ipath_post_receive() won't fill the empty slot. | ||
| 544 | */ | ||
| 545 | if (qp->ibqp.srq) { | ||
| 546 | srq = to_isrq(qp->ibqp.srq); | ||
| 547 | rq = &srq->rq; | ||
| 548 | } else { | ||
| 549 | srq = NULL; | ||
| 550 | rq = &qp->r_rq; | ||
| 551 | } | ||
| 552 | spin_lock_irqsave(&rq->lock, flags); | ||
| 553 | if (rq->tail == rq->head) { | ||
| 554 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 555 | dev->n_pkt_drops++; | ||
| 556 | goto bail; | ||
| 557 | } | ||
| 558 | /* Silently drop packets which are too big. */ | ||
| 559 | wqe = get_rwqe_ptr(rq, rq->tail); | ||
| 560 | if (wc.byte_len > wqe->length) { | ||
| 561 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 562 | dev->n_pkt_drops++; | ||
| 563 | goto bail; | ||
| 564 | } | ||
| 565 | wc.wr_id = wqe->wr_id; | ||
| 566 | qp->r_sge.sge = wqe->sg_list[0]; | ||
| 567 | qp->r_sge.sg_list = wqe->sg_list + 1; | ||
| 568 | qp->r_sge.num_sge = wqe->num_sge; | ||
| 569 | if (++rq->tail >= rq->size) | ||
| 570 | rq->tail = 0; | ||
| 571 | if (srq && srq->ibsrq.event_handler) { | ||
| 572 | u32 n; | ||
| 573 | |||
| 574 | if (rq->head < rq->tail) | ||
| 575 | n = rq->size + rq->head - rq->tail; | ||
| 576 | else | ||
| 577 | n = rq->head - rq->tail; | ||
| 578 | if (n < srq->limit) { | ||
| 579 | struct ib_event ev; | ||
| 580 | |||
| 581 | srq->limit = 0; | ||
| 582 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 583 | ev.device = qp->ibqp.device; | ||
| 584 | ev.element.srq = qp->ibqp.srq; | ||
| 585 | ev.event = IB_EVENT_SRQ_LIMIT_REACHED; | ||
| 586 | srq->ibsrq.event_handler(&ev, | ||
| 587 | srq->ibsrq.srq_context); | ||
| 588 | } else | ||
| 589 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 590 | } else | ||
| 591 | spin_unlock_irqrestore(&rq->lock, flags); | ||
| 592 | if (has_grh) { | ||
| 593 | ipath_copy_sge(&qp->r_sge, &hdr->u.l.grh, | ||
| 594 | sizeof(struct ib_grh)); | ||
| 595 | wc.wc_flags |= IB_WC_GRH; | ||
| 596 | } else | ||
| 597 | ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh)); | ||
| 598 | ipath_copy_sge(&qp->r_sge, data, | ||
| 599 | wc.byte_len - sizeof(struct ib_grh)); | ||
| 600 | wc.status = IB_WC_SUCCESS; | ||
| 601 | wc.opcode = IB_WC_RECV; | ||
| 602 | wc.vendor_err = 0; | ||
| 603 | wc.qp_num = qp->ibqp.qp_num; | ||
| 604 | wc.src_qp = src_qp; | ||
| 605 | /* XXX do we know which pkey matched? Only needed for GSI. */ | ||
| 606 | wc.pkey_index = 0; | ||
| 607 | wc.slid = be16_to_cpu(hdr->lrh[3]); | ||
| 608 | wc.sl = (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF; | ||
| 609 | dlid = be16_to_cpu(hdr->lrh[1]); | ||
| 610 | /* | ||
| 611 | * Save the LMC lower bits if the destination LID is a unicast LID. | ||
| 612 | */ | ||
| 613 | wc.dlid_path_bits = dlid >= IPS_MULTICAST_LID_BASE ? 0 : | ||
| 614 | dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | ||
| 615 | /* Signal completion event if the solicited bit is set. */ | ||
| 616 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | ||
| 617 | (ohdr->bth[0] & | ||
| 618 | __constant_cpu_to_be32(1 << 23)) != 0); | ||
| 619 | |||
| 620 | bail:; | ||
| 621 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c new file mode 100644 index 000000000000..2bb08afc86d0 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/mm.h> | ||
| 34 | #include <linux/device.h> | ||
| 35 | |||
| 36 | #include "ipath_kernel.h" | ||
| 37 | |||
| 38 | static void __ipath_release_user_pages(struct page **p, size_t num_pages, | ||
| 39 | int dirty) | ||
| 40 | { | ||
| 41 | size_t i; | ||
| 42 | |||
| 43 | for (i = 0; i < num_pages; i++) { | ||
| 44 | ipath_cdbg(MM, "%lu/%lu put_page %p\n", (unsigned long) i, | ||
| 45 | (unsigned long) num_pages, p[i]); | ||
| 46 | if (dirty) | ||
| 47 | set_page_dirty_lock(p[i]); | ||
| 48 | put_page(p[i]); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /* call with current->mm->mmap_sem held */ | ||
| 53 | static int __get_user_pages(unsigned long start_page, size_t num_pages, | ||
| 54 | struct page **p, struct vm_area_struct **vma) | ||
| 55 | { | ||
| 56 | unsigned long lock_limit; | ||
| 57 | size_t got; | ||
| 58 | int ret; | ||
| 59 | |||
| 60 | #if 0 | ||
| 61 | /* | ||
| 62 | * XXX - causes MPI programs to fail, haven't had time to check | ||
| 63 | * yet | ||
| 64 | */ | ||
| 65 | if (!capable(CAP_IPC_LOCK)) { | ||
| 66 | ret = -EPERM; | ||
| 67 | goto bail; | ||
| 68 | } | ||
| 69 | #endif | ||
| 70 | |||
| 71 | lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> | ||
| 72 | PAGE_SHIFT; | ||
| 73 | |||
| 74 | if (num_pages > lock_limit) { | ||
| 75 | ret = -ENOMEM; | ||
| 76 | goto bail; | ||
| 77 | } | ||
| 78 | |||
| 79 | ipath_cdbg(VERBOSE, "pin %lx pages from vaddr %lx\n", | ||
| 80 | (unsigned long) num_pages, start_page); | ||
| 81 | |||
| 82 | for (got = 0; got < num_pages; got += ret) { | ||
| 83 | ret = get_user_pages(current, current->mm, | ||
| 84 | start_page + got * PAGE_SIZE, | ||
| 85 | num_pages - got, 1, 1, | ||
| 86 | p + got, vma); | ||
| 87 | if (ret < 0) | ||
| 88 | goto bail_release; | ||
| 89 | } | ||
| 90 | |||
| 91 | current->mm->locked_vm += num_pages; | ||
| 92 | |||
| 93 | ret = 0; | ||
| 94 | goto bail; | ||
| 95 | |||
| 96 | bail_release: | ||
| 97 | __ipath_release_user_pages(p, got, 0); | ||
| 98 | bail: | ||
| 99 | return ret; | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * ipath_get_user_pages - lock user pages into memory | ||
| 104 | * @start_page: the start page | ||
| 105 | * @num_pages: the number of pages | ||
| 106 | * @p: the output page structures | ||
| 107 | * | ||
| 108 | * This function takes a given start page (page aligned user virtual | ||
| 109 | * address) and pins it and the following specified number of pages. For | ||
| 110 | * now, num_pages is always 1, but that will probably change at some point | ||
| 111 | * (because caller is doing expected sends on a single virtually contiguous | ||
| 112 | * buffer, so we can do all pages at once). | ||
| 113 | */ | ||
| 114 | int ipath_get_user_pages(unsigned long start_page, size_t num_pages, | ||
| 115 | struct page **p) | ||
| 116 | { | ||
| 117 | int ret; | ||
| 118 | |||
| 119 | down_write(¤t->mm->mmap_sem); | ||
| 120 | |||
| 121 | ret = __get_user_pages(start_page, num_pages, p, NULL); | ||
| 122 | |||
| 123 | up_write(¤t->mm->mmap_sem); | ||
| 124 | |||
| 125 | return ret; | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * ipath_get_user_pages_nocopy - lock a single page for I/O and mark shared | ||
| 130 | * @start_page: the page to lock | ||
| 131 | * @p: the output page structure | ||
| 132 | * | ||
| 133 | * This is similar to ipath_get_user_pages, but it's always one page, and we | ||
| 134 | * mark the page as locked for I/O, and shared. This is used for the user | ||
| 135 | * process page that contains the destination address for the rcvhdrq tail | ||
| 136 | * update, so we need to have the vma. If we don't do this, the page can be | ||
| 137 | * taken away from us on fork, even if the child never touches it, and then | ||
| 138 | * the user process never sees the tail register updates. | ||
| 139 | */ | ||
| 140 | int ipath_get_user_pages_nocopy(unsigned long page, struct page **p) | ||
| 141 | { | ||
| 142 | struct vm_area_struct *vma; | ||
| 143 | int ret; | ||
| 144 | |||
| 145 | down_write(¤t->mm->mmap_sem); | ||
| 146 | |||
| 147 | ret = __get_user_pages(page, 1, p, &vma); | ||
| 148 | |||
| 149 | up_write(¤t->mm->mmap_sem); | ||
| 150 | |||
| 151 | return ret; | ||
| 152 | } | ||
| 153 | |||
| 154 | void ipath_release_user_pages(struct page **p, size_t num_pages) | ||
| 155 | { | ||
| 156 | down_write(¤t->mm->mmap_sem); | ||
| 157 | |||
| 158 | __ipath_release_user_pages(p, num_pages, 1); | ||
| 159 | |||
| 160 | current->mm->locked_vm -= num_pages; | ||
| 161 | |||
| 162 | up_write(¤t->mm->mmap_sem); | ||
| 163 | } | ||
| 164 | |||
| 165 | struct ipath_user_pages_work { | ||
| 166 | struct work_struct work; | ||
| 167 | struct mm_struct *mm; | ||
| 168 | unsigned long num_pages; | ||
| 169 | }; | ||
| 170 | |||
| 171 | static void user_pages_account(void *ptr) | ||
| 172 | { | ||
| 173 | struct ipath_user_pages_work *work = ptr; | ||
| 174 | |||
| 175 | down_write(&work->mm->mmap_sem); | ||
| 176 | work->mm->locked_vm -= work->num_pages; | ||
| 177 | up_write(&work->mm->mmap_sem); | ||
| 178 | mmput(work->mm); | ||
| 179 | kfree(work); | ||
| 180 | } | ||
| 181 | |||
| 182 | void ipath_release_user_pages_on_close(struct page **p, size_t num_pages) | ||
| 183 | { | ||
| 184 | struct ipath_user_pages_work *work; | ||
| 185 | struct mm_struct *mm; | ||
| 186 | |||
| 187 | __ipath_release_user_pages(p, num_pages, 1); | ||
| 188 | |||
| 189 | mm = get_task_mm(current); | ||
| 190 | if (!mm) | ||
| 191 | goto bail; | ||
| 192 | |||
| 193 | work = kmalloc(sizeof(*work), GFP_KERNEL); | ||
| 194 | if (!work) | ||
| 195 | goto bail_mm; | ||
| 196 | |||
| 197 | goto bail; | ||
| 198 | |||
| 199 | INIT_WORK(&work->work, user_pages_account, work); | ||
| 200 | work->mm = mm; | ||
| 201 | work->num_pages = num_pages; | ||
| 202 | |||
| 203 | bail_mm: | ||
| 204 | mmput(mm); | ||
| 205 | bail: | ||
| 206 | return; | ||
| 207 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c new file mode 100644 index 000000000000..9f27fd35cdbb --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
| @@ -0,0 +1,1222 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <rdma/ib_mad.h> | ||
| 34 | #include <rdma/ib_user_verbs.h> | ||
| 35 | #include <linux/utsname.h> | ||
| 36 | |||
| 37 | #include "ipath_kernel.h" | ||
| 38 | #include "ipath_verbs.h" | ||
| 39 | #include "ips_common.h" | ||
| 40 | |||
| 41 | /* Not static, because we don't want the compiler removing it */ | ||
| 42 | const char ipath_verbs_version[] = "ipath_verbs " IPATH_IDSTR; | ||
| 43 | |||
| 44 | unsigned int ib_ipath_qp_table_size = 251; | ||
| 45 | module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO); | ||
| 46 | MODULE_PARM_DESC(qp_table_size, "QP table size"); | ||
| 47 | |||
| 48 | unsigned int ib_ipath_lkey_table_size = 12; | ||
| 49 | module_param_named(lkey_table_size, ib_ipath_lkey_table_size, uint, | ||
| 50 | S_IRUGO); | ||
| 51 | MODULE_PARM_DESC(lkey_table_size, | ||
| 52 | "LKEY table size in bits (2^n, 1 <= n <= 23)"); | ||
| 53 | |||
| 54 | unsigned int ib_ipath_debug; /* debug mask */ | ||
| 55 | module_param_named(debug, ib_ipath_debug, uint, S_IWUSR | S_IRUGO); | ||
| 56 | MODULE_PARM_DESC(debug, "Verbs debug mask"); | ||
| 57 | |||
| 58 | MODULE_LICENSE("GPL"); | ||
| 59 | MODULE_AUTHOR("PathScale <support@pathscale.com>"); | ||
| 60 | MODULE_DESCRIPTION("Pathscale InfiniPath driver"); | ||
| 61 | |||
| 62 | const int ib_ipath_state_ops[IB_QPS_ERR + 1] = { | ||
| 63 | [IB_QPS_RESET] = 0, | ||
| 64 | [IB_QPS_INIT] = IPATH_POST_RECV_OK, | ||
| 65 | [IB_QPS_RTR] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK, | ||
| 66 | [IB_QPS_RTS] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK | | ||
| 67 | IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK, | ||
| 68 | [IB_QPS_SQD] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK | | ||
| 69 | IPATH_POST_SEND_OK, | ||
| 70 | [IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK, | ||
| 71 | [IB_QPS_ERR] = 0, | ||
| 72 | }; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Translate ib_wr_opcode into ib_wc_opcode. | ||
| 76 | */ | ||
| 77 | const enum ib_wc_opcode ib_ipath_wc_opcode[] = { | ||
| 78 | [IB_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE, | ||
| 79 | [IB_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE, | ||
| 80 | [IB_WR_SEND] = IB_WC_SEND, | ||
| 81 | [IB_WR_SEND_WITH_IMM] = IB_WC_SEND, | ||
| 82 | [IB_WR_RDMA_READ] = IB_WC_RDMA_READ, | ||
| 83 | [IB_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP, | ||
| 84 | [IB_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD | ||
| 85 | }; | ||
| 86 | |||
| 87 | /* | ||
| 88 | * System image GUID. | ||
| 89 | */ | ||
| 90 | __be64 sys_image_guid; | ||
| 91 | |||
| 92 | /** | ||
| 93 | * ipath_copy_sge - copy data to SGE memory | ||
| 94 | * @ss: the SGE state | ||
| 95 | * @data: the data to copy | ||
| 96 | * @length: the length of the data | ||
| 97 | */ | ||
| 98 | void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length) | ||
| 99 | { | ||
| 100 | struct ipath_sge *sge = &ss->sge; | ||
| 101 | |||
| 102 | while (length) { | ||
| 103 | u32 len = sge->length; | ||
| 104 | |||
| 105 | BUG_ON(len == 0); | ||
| 106 | if (len > length) | ||
| 107 | len = length; | ||
| 108 | memcpy(sge->vaddr, data, len); | ||
| 109 | sge->vaddr += len; | ||
| 110 | sge->length -= len; | ||
| 111 | sge->sge_length -= len; | ||
| 112 | if (sge->sge_length == 0) { | ||
| 113 | if (--ss->num_sge) | ||
| 114 | *sge = *ss->sg_list++; | ||
| 115 | } else if (sge->length == 0 && sge->mr != NULL) { | ||
| 116 | if (++sge->n >= IPATH_SEGSZ) { | ||
| 117 | if (++sge->m >= sge->mr->mapsz) | ||
| 118 | break; | ||
| 119 | sge->n = 0; | ||
| 120 | } | ||
| 121 | sge->vaddr = | ||
| 122 | sge->mr->map[sge->m]->segs[sge->n].vaddr; | ||
| 123 | sge->length = | ||
| 124 | sge->mr->map[sge->m]->segs[sge->n].length; | ||
| 125 | } | ||
| 126 | data += len; | ||
| 127 | length -= len; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * ipath_skip_sge - skip over SGE memory - XXX almost dup of prev func | ||
| 133 | * @ss: the SGE state | ||
| 134 | * @length: the number of bytes to skip | ||
| 135 | */ | ||
| 136 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length) | ||
| 137 | { | ||
| 138 | struct ipath_sge *sge = &ss->sge; | ||
| 139 | |||
| 140 | while (length > sge->sge_length) { | ||
| 141 | length -= sge->sge_length; | ||
| 142 | ss->sge = *ss->sg_list++; | ||
| 143 | } | ||
| 144 | while (length) { | ||
| 145 | u32 len = sge->length; | ||
| 146 | |||
| 147 | BUG_ON(len == 0); | ||
| 148 | if (len > length) | ||
| 149 | len = length; | ||
| 150 | sge->vaddr += len; | ||
| 151 | sge->length -= len; | ||
| 152 | sge->sge_length -= len; | ||
| 153 | if (sge->sge_length == 0) { | ||
| 154 | if (--ss->num_sge) | ||
| 155 | *sge = *ss->sg_list++; | ||
| 156 | } else if (sge->length == 0 && sge->mr != NULL) { | ||
| 157 | if (++sge->n >= IPATH_SEGSZ) { | ||
| 158 | if (++sge->m >= sge->mr->mapsz) | ||
| 159 | break; | ||
| 160 | sge->n = 0; | ||
| 161 | } | ||
| 162 | sge->vaddr = | ||
| 163 | sge->mr->map[sge->m]->segs[sge->n].vaddr; | ||
| 164 | sge->length = | ||
| 165 | sge->mr->map[sge->m]->segs[sge->n].length; | ||
| 166 | } | ||
| 167 | length -= len; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * ipath_post_send - post a send on a QP | ||
| 173 | * @ibqp: the QP to post the send on | ||
| 174 | * @wr: the list of work requests to post | ||
| 175 | * @bad_wr: the first bad WR is put here | ||
| 176 | * | ||
| 177 | * This may be called from interrupt context. | ||
| 178 | */ | ||
| 179 | static int ipath_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | ||
| 180 | struct ib_send_wr **bad_wr) | ||
| 181 | { | ||
| 182 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 183 | int err = 0; | ||
| 184 | |||
| 185 | /* Check that state is OK to post send. */ | ||
| 186 | if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)) { | ||
| 187 | *bad_wr = wr; | ||
| 188 | err = -EINVAL; | ||
| 189 | goto bail; | ||
| 190 | } | ||
| 191 | |||
| 192 | for (; wr; wr = wr->next) { | ||
| 193 | switch (qp->ibqp.qp_type) { | ||
| 194 | case IB_QPT_UC: | ||
| 195 | case IB_QPT_RC: | ||
| 196 | err = ipath_post_rc_send(qp, wr); | ||
| 197 | break; | ||
| 198 | |||
| 199 | case IB_QPT_SMI: | ||
| 200 | case IB_QPT_GSI: | ||
| 201 | case IB_QPT_UD: | ||
| 202 | err = ipath_post_ud_send(qp, wr); | ||
| 203 | break; | ||
| 204 | |||
| 205 | default: | ||
| 206 | err = -EINVAL; | ||
| 207 | } | ||
| 208 | if (err) { | ||
| 209 | *bad_wr = wr; | ||
| 210 | break; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | bail: | ||
| 215 | return err; | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * ipath_post_receive - post a receive on a QP | ||
| 220 | * @ibqp: the QP to post the receive on | ||
| 221 | * @wr: the WR to post | ||
| 222 | * @bad_wr: the first bad WR is put here | ||
| 223 | * | ||
| 224 | * This may be called from interrupt context. | ||
| 225 | */ | ||
| 226 | static int ipath_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | ||
| 227 | struct ib_recv_wr **bad_wr) | ||
| 228 | { | ||
| 229 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 230 | unsigned long flags; | ||
| 231 | int ret; | ||
| 232 | |||
| 233 | /* Check that state is OK to post receive. */ | ||
| 234 | if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_RECV_OK)) { | ||
| 235 | *bad_wr = wr; | ||
| 236 | ret = -EINVAL; | ||
| 237 | goto bail; | ||
| 238 | } | ||
| 239 | |||
| 240 | for (; wr; wr = wr->next) { | ||
| 241 | struct ipath_rwqe *wqe; | ||
| 242 | u32 next; | ||
| 243 | int i, j; | ||
| 244 | |||
| 245 | if (wr->num_sge > qp->r_rq.max_sge) { | ||
| 246 | *bad_wr = wr; | ||
| 247 | ret = -ENOMEM; | ||
| 248 | goto bail; | ||
| 249 | } | ||
| 250 | |||
| 251 | spin_lock_irqsave(&qp->r_rq.lock, flags); | ||
| 252 | next = qp->r_rq.head + 1; | ||
| 253 | if (next >= qp->r_rq.size) | ||
| 254 | next = 0; | ||
| 255 | if (next == qp->r_rq.tail) { | ||
| 256 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 257 | *bad_wr = wr; | ||
| 258 | ret = -ENOMEM; | ||
| 259 | goto bail; | ||
| 260 | } | ||
| 261 | |||
| 262 | wqe = get_rwqe_ptr(&qp->r_rq, qp->r_rq.head); | ||
| 263 | wqe->wr_id = wr->wr_id; | ||
| 264 | wqe->sg_list[0].mr = NULL; | ||
| 265 | wqe->sg_list[0].vaddr = NULL; | ||
| 266 | wqe->sg_list[0].length = 0; | ||
| 267 | wqe->sg_list[0].sge_length = 0; | ||
| 268 | wqe->length = 0; | ||
| 269 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
| 270 | /* Check LKEY */ | ||
| 271 | if (to_ipd(qp->ibqp.pd)->user && | ||
| 272 | wr->sg_list[i].lkey == 0) { | ||
| 273 | spin_unlock_irqrestore(&qp->r_rq.lock, | ||
| 274 | flags); | ||
| 275 | *bad_wr = wr; | ||
| 276 | ret = -EINVAL; | ||
| 277 | goto bail; | ||
| 278 | } | ||
| 279 | if (wr->sg_list[i].length == 0) | ||
| 280 | continue; | ||
| 281 | if (!ipath_lkey_ok( | ||
| 282 | &to_idev(qp->ibqp.device)->lk_table, | ||
| 283 | &wqe->sg_list[j], &wr->sg_list[i], | ||
| 284 | IB_ACCESS_LOCAL_WRITE)) { | ||
| 285 | spin_unlock_irqrestore(&qp->r_rq.lock, | ||
| 286 | flags); | ||
| 287 | *bad_wr = wr; | ||
| 288 | ret = -EINVAL; | ||
| 289 | goto bail; | ||
| 290 | } | ||
| 291 | wqe->length += wr->sg_list[i].length; | ||
| 292 | j++; | ||
| 293 | } | ||
| 294 | wqe->num_sge = j; | ||
| 295 | qp->r_rq.head = next; | ||
| 296 | spin_unlock_irqrestore(&qp->r_rq.lock, flags); | ||
| 297 | } | ||
| 298 | ret = 0; | ||
| 299 | |||
| 300 | bail: | ||
| 301 | return ret; | ||
| 302 | } | ||
| 303 | |||
| 304 | /** | ||
| 305 | * ipath_qp_rcv - processing an incoming packet on a QP | ||
| 306 | * @dev: the device the packet came on | ||
| 307 | * @hdr: the packet header | ||
| 308 | * @has_grh: true if the packet has a GRH | ||
| 309 | * @data: the packet data | ||
| 310 | * @tlen: the packet length | ||
| 311 | * @qp: the QP the packet came on | ||
| 312 | * | ||
| 313 | * This is called from ipath_ib_rcv() to process an incoming packet | ||
| 314 | * for the given QP. | ||
| 315 | * Called at interrupt level. | ||
| 316 | */ | ||
| 317 | static void ipath_qp_rcv(struct ipath_ibdev *dev, | ||
| 318 | struct ipath_ib_header *hdr, int has_grh, | ||
| 319 | void *data, u32 tlen, struct ipath_qp *qp) | ||
| 320 | { | ||
| 321 | /* Check for valid receive state. */ | ||
| 322 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) { | ||
| 323 | dev->n_pkt_drops++; | ||
| 324 | return; | ||
| 325 | } | ||
| 326 | |||
| 327 | switch (qp->ibqp.qp_type) { | ||
| 328 | case IB_QPT_SMI: | ||
| 329 | case IB_QPT_GSI: | ||
| 330 | case IB_QPT_UD: | ||
| 331 | ipath_ud_rcv(dev, hdr, has_grh, data, tlen, qp); | ||
| 332 | break; | ||
| 333 | |||
| 334 | case IB_QPT_RC: | ||
| 335 | ipath_rc_rcv(dev, hdr, has_grh, data, tlen, qp); | ||
| 336 | break; | ||
| 337 | |||
| 338 | case IB_QPT_UC: | ||
| 339 | ipath_uc_rcv(dev, hdr, has_grh, data, tlen, qp); | ||
| 340 | break; | ||
| 341 | |||
| 342 | default: | ||
| 343 | break; | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | /** | ||
| 348 | * ipath_ib_rcv - process and incoming packet | ||
| 349 | * @arg: the device pointer | ||
| 350 | * @rhdr: the header of the packet | ||
| 351 | * @data: the packet data | ||
| 352 | * @tlen: the packet length | ||
| 353 | * | ||
| 354 | * This is called from ipath_kreceive() to process an incoming packet at | ||
| 355 | * interrupt level. Tlen is the length of the header + data + CRC in bytes. | ||
| 356 | */ | ||
| 357 | static void ipath_ib_rcv(void *arg, void *rhdr, void *data, u32 tlen) | ||
| 358 | { | ||
| 359 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; | ||
| 360 | struct ipath_ib_header *hdr = rhdr; | ||
| 361 | struct ipath_other_headers *ohdr; | ||
| 362 | struct ipath_qp *qp; | ||
| 363 | u32 qp_num; | ||
| 364 | int lnh; | ||
| 365 | u8 opcode; | ||
| 366 | u16 lid; | ||
| 367 | |||
| 368 | if (unlikely(dev == NULL)) | ||
| 369 | goto bail; | ||
| 370 | |||
| 371 | if (unlikely(tlen < 24)) { /* LRH+BTH+CRC */ | ||
| 372 | dev->rcv_errors++; | ||
| 373 | goto bail; | ||
| 374 | } | ||
| 375 | |||
| 376 | /* Check for a valid destination LID (see ch. 7.11.1). */ | ||
| 377 | lid = be16_to_cpu(hdr->lrh[1]); | ||
| 378 | if (lid < IPS_MULTICAST_LID_BASE) { | ||
| 379 | lid &= ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | ||
| 380 | if (unlikely(lid != ipath_layer_get_lid(dev->dd))) { | ||
| 381 | dev->rcv_errors++; | ||
| 382 | goto bail; | ||
| 383 | } | ||
| 384 | } | ||
| 385 | |||
| 386 | /* Check for GRH */ | ||
| 387 | lnh = be16_to_cpu(hdr->lrh[0]) & 3; | ||
| 388 | if (lnh == IPS_LRH_BTH) | ||
| 389 | ohdr = &hdr->u.oth; | ||
| 390 | else if (lnh == IPS_LRH_GRH) | ||
| 391 | ohdr = &hdr->u.l.oth; | ||
| 392 | else { | ||
| 393 | dev->rcv_errors++; | ||
| 394 | goto bail; | ||
| 395 | } | ||
| 396 | |||
| 397 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | ||
| 398 | dev->opstats[opcode].n_bytes += tlen; | ||
| 399 | dev->opstats[opcode].n_packets++; | ||
| 400 | |||
| 401 | /* Get the destination QP number. */ | ||
| 402 | qp_num = be32_to_cpu(ohdr->bth[1]) & IPS_QPN_MASK; | ||
| 403 | if (qp_num == IPS_MULTICAST_QPN) { | ||
| 404 | struct ipath_mcast *mcast; | ||
| 405 | struct ipath_mcast_qp *p; | ||
| 406 | |||
| 407 | mcast = ipath_mcast_find(&hdr->u.l.grh.dgid); | ||
| 408 | if (mcast == NULL) { | ||
| 409 | dev->n_pkt_drops++; | ||
| 410 | goto bail; | ||
| 411 | } | ||
| 412 | dev->n_multicast_rcv++; | ||
| 413 | list_for_each_entry_rcu(p, &mcast->qp_list, list) | ||
| 414 | ipath_qp_rcv(dev, hdr, lnh == IPS_LRH_GRH, data, | ||
| 415 | tlen, p->qp); | ||
| 416 | /* | ||
| 417 | * Notify ipath_multicast_detach() if it is waiting for us | ||
| 418 | * to finish. | ||
| 419 | */ | ||
| 420 | if (atomic_dec_return(&mcast->refcount) <= 1) | ||
| 421 | wake_up(&mcast->wait); | ||
| 422 | } else { | ||
| 423 | qp = ipath_lookup_qpn(&dev->qp_table, qp_num); | ||
| 424 | if (qp) { | ||
| 425 | dev->n_unicast_rcv++; | ||
| 426 | ipath_qp_rcv(dev, hdr, lnh == IPS_LRH_GRH, data, | ||
| 427 | tlen, qp); | ||
| 428 | /* | ||
| 429 | * Notify ipath_destroy_qp() if it is waiting | ||
| 430 | * for us to finish. | ||
| 431 | */ | ||
| 432 | if (atomic_dec_and_test(&qp->refcount)) | ||
| 433 | wake_up(&qp->wait); | ||
| 434 | } else | ||
| 435 | dev->n_pkt_drops++; | ||
| 436 | } | ||
| 437 | |||
| 438 | bail:; | ||
| 439 | } | ||
| 440 | |||
| 441 | /** | ||
| 442 | * ipath_ib_timer - verbs timer | ||
| 443 | * @arg: the device pointer | ||
| 444 | * | ||
| 445 | * This is called from ipath_do_rcv_timer() at interrupt level to check for | ||
| 446 | * QPs which need retransmits and to collect performance numbers. | ||
| 447 | */ | ||
| 448 | static void ipath_ib_timer(void *arg) | ||
| 449 | { | ||
| 450 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; | ||
| 451 | struct ipath_qp *resend = NULL; | ||
| 452 | struct ipath_qp *rnr = NULL; | ||
| 453 | struct list_head *last; | ||
| 454 | struct ipath_qp *qp; | ||
| 455 | unsigned long flags; | ||
| 456 | |||
| 457 | if (dev == NULL) | ||
| 458 | return; | ||
| 459 | |||
| 460 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 461 | /* Start filling the next pending queue. */ | ||
| 462 | if (++dev->pending_index >= ARRAY_SIZE(dev->pending)) | ||
| 463 | dev->pending_index = 0; | ||
| 464 | /* Save any requests still in the new queue, they have timed out. */ | ||
| 465 | last = &dev->pending[dev->pending_index]; | ||
| 466 | while (!list_empty(last)) { | ||
| 467 | qp = list_entry(last->next, struct ipath_qp, timerwait); | ||
| 468 | if (last->next == LIST_POISON1 || | ||
| 469 | last->next != &qp->timerwait || | ||
| 470 | qp->timerwait.prev != last) { | ||
| 471 | INIT_LIST_HEAD(last); | ||
| 472 | } else { | ||
| 473 | list_del(&qp->timerwait); | ||
| 474 | qp->timerwait.prev = (struct list_head *) resend; | ||
| 475 | resend = qp; | ||
| 476 | atomic_inc(&qp->refcount); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | last = &dev->rnrwait; | ||
| 480 | if (!list_empty(last)) { | ||
| 481 | qp = list_entry(last->next, struct ipath_qp, timerwait); | ||
| 482 | if (--qp->s_rnr_timeout == 0) { | ||
| 483 | do { | ||
| 484 | if (last->next == LIST_POISON1 || | ||
| 485 | last->next != &qp->timerwait || | ||
| 486 | qp->timerwait.prev != last) { | ||
| 487 | INIT_LIST_HEAD(last); | ||
| 488 | break; | ||
| 489 | } | ||
| 490 | list_del(&qp->timerwait); | ||
| 491 | qp->timerwait.prev = | ||
| 492 | (struct list_head *) rnr; | ||
| 493 | rnr = qp; | ||
| 494 | if (list_empty(last)) | ||
| 495 | break; | ||
| 496 | qp = list_entry(last->next, struct ipath_qp, | ||
| 497 | timerwait); | ||
| 498 | } while (qp->s_rnr_timeout == 0); | ||
| 499 | } | ||
| 500 | } | ||
| 501 | /* | ||
| 502 | * We should only be in the started state if pma_sample_start != 0 | ||
| 503 | */ | ||
| 504 | if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_STARTED && | ||
| 505 | --dev->pma_sample_start == 0) { | ||
| 506 | dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_RUNNING; | ||
| 507 | ipath_layer_snapshot_counters(dev->dd, &dev->ipath_sword, | ||
| 508 | &dev->ipath_rword, | ||
| 509 | &dev->ipath_spkts, | ||
| 510 | &dev->ipath_rpkts, | ||
| 511 | &dev->ipath_xmit_wait); | ||
| 512 | } | ||
| 513 | if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_RUNNING) { | ||
| 514 | if (dev->pma_sample_interval == 0) { | ||
| 515 | u64 ta, tb, tc, td, te; | ||
| 516 | |||
| 517 | dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_DONE; | ||
| 518 | ipath_layer_snapshot_counters(dev->dd, &ta, &tb, | ||
| 519 | &tc, &td, &te); | ||
| 520 | |||
| 521 | dev->ipath_sword = ta - dev->ipath_sword; | ||
| 522 | dev->ipath_rword = tb - dev->ipath_rword; | ||
| 523 | dev->ipath_spkts = tc - dev->ipath_spkts; | ||
| 524 | dev->ipath_rpkts = td - dev->ipath_rpkts; | ||
| 525 | dev->ipath_xmit_wait = te - dev->ipath_xmit_wait; | ||
| 526 | } | ||
| 527 | else | ||
| 528 | dev->pma_sample_interval--; | ||
| 529 | } | ||
| 530 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 531 | |||
| 532 | /* XXX What if timer fires again while this is running? */ | ||
| 533 | for (qp = resend; qp != NULL; | ||
| 534 | qp = (struct ipath_qp *) qp->timerwait.prev) { | ||
| 535 | struct ib_wc wc; | ||
| 536 | |||
| 537 | spin_lock_irqsave(&qp->s_lock, flags); | ||
| 538 | if (qp->s_last != qp->s_tail && qp->state == IB_QPS_RTS) { | ||
| 539 | dev->n_timeouts++; | ||
| 540 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | ||
| 541 | } | ||
| 542 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
| 543 | |||
| 544 | /* Notify ipath_destroy_qp() if it is waiting. */ | ||
| 545 | if (atomic_dec_and_test(&qp->refcount)) | ||
| 546 | wake_up(&qp->wait); | ||
| 547 | } | ||
| 548 | for (qp = rnr; qp != NULL; | ||
| 549 | qp = (struct ipath_qp *) qp->timerwait.prev) | ||
| 550 | tasklet_hi_schedule(&qp->s_task); | ||
| 551 | } | ||
| 552 | |||
| 553 | /** | ||
| 554 | * ipath_ib_piobufavail - callback when a PIO buffer is available | ||
| 555 | * @arg: the device pointer | ||
| 556 | * | ||
| 557 | * This is called from ipath_intr() at interrupt level when a PIO buffer is | ||
| 558 | * available after ipath_verbs_send() returned an error that no buffers were | ||
| 559 | * available. Return 0 if we consumed all the PIO buffers and we still have | ||
| 560 | * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and | ||
| 561 | * return one). | ||
| 562 | */ | ||
| 563 | static int ipath_ib_piobufavail(void *arg) | ||
| 564 | { | ||
| 565 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; | ||
| 566 | struct ipath_qp *qp; | ||
| 567 | unsigned long flags; | ||
| 568 | |||
| 569 | if (dev == NULL) | ||
| 570 | goto bail; | ||
| 571 | |||
| 572 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
| 573 | while (!list_empty(&dev->piowait)) { | ||
| 574 | qp = list_entry(dev->piowait.next, struct ipath_qp, | ||
| 575 | piowait); | ||
| 576 | list_del(&qp->piowait); | ||
| 577 | tasklet_hi_schedule(&qp->s_task); | ||
| 578 | } | ||
| 579 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 580 | |||
| 581 | bail: | ||
| 582 | return 1; | ||
| 583 | } | ||
| 584 | |||
| 585 | static int ipath_query_device(struct ib_device *ibdev, | ||
| 586 | struct ib_device_attr *props) | ||
| 587 | { | ||
| 588 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 589 | u32 vendor, boardrev, majrev, minrev; | ||
| 590 | |||
| 591 | memset(props, 0, sizeof(*props)); | ||
| 592 | |||
| 593 | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | | ||
| 594 | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | | ||
| 595 | IB_DEVICE_SYS_IMAGE_GUID; | ||
| 596 | ipath_layer_query_device(dev->dd, &vendor, &boardrev, | ||
| 597 | &majrev, &minrev); | ||
| 598 | props->vendor_id = vendor; | ||
| 599 | props->vendor_part_id = boardrev; | ||
| 600 | props->hw_ver = boardrev << 16 | majrev << 8 | minrev; | ||
| 601 | |||
| 602 | props->sys_image_guid = dev->sys_image_guid; | ||
| 603 | |||
| 604 | props->max_mr_size = ~0ull; | ||
| 605 | props->max_qp = 0xffff; | ||
| 606 | props->max_qp_wr = 0xffff; | ||
| 607 | props->max_sge = 255; | ||
| 608 | props->max_cq = 0xffff; | ||
| 609 | props->max_cqe = 0xffff; | ||
| 610 | props->max_mr = 0xffff; | ||
| 611 | props->max_pd = 0xffff; | ||
| 612 | props->max_qp_rd_atom = 1; | ||
| 613 | props->max_qp_init_rd_atom = 1; | ||
| 614 | /* props->max_res_rd_atom */ | ||
| 615 | props->max_srq = 0xffff; | ||
| 616 | props->max_srq_wr = 0xffff; | ||
| 617 | props->max_srq_sge = 255; | ||
| 618 | /* props->local_ca_ack_delay */ | ||
| 619 | props->atomic_cap = IB_ATOMIC_HCA; | ||
| 620 | props->max_pkeys = ipath_layer_get_npkeys(dev->dd); | ||
| 621 | props->max_mcast_grp = 0xffff; | ||
| 622 | props->max_mcast_qp_attach = 0xffff; | ||
| 623 | props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * | ||
| 624 | props->max_mcast_grp; | ||
| 625 | |||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | const u8 ipath_cvt_physportstate[16] = { | ||
| 630 | [INFINIPATH_IBCS_LT_STATE_DISABLED] = 3, | ||
| 631 | [INFINIPATH_IBCS_LT_STATE_LINKUP] = 5, | ||
| 632 | [INFINIPATH_IBCS_LT_STATE_POLLACTIVE] = 2, | ||
| 633 | [INFINIPATH_IBCS_LT_STATE_POLLQUIET] = 2, | ||
| 634 | [INFINIPATH_IBCS_LT_STATE_SLEEPDELAY] = 1, | ||
| 635 | [INFINIPATH_IBCS_LT_STATE_SLEEPQUIET] = 1, | ||
| 636 | [INFINIPATH_IBCS_LT_STATE_CFGDEBOUNCE] = 4, | ||
| 637 | [INFINIPATH_IBCS_LT_STATE_CFGRCVFCFG] = 4, | ||
| 638 | [INFINIPATH_IBCS_LT_STATE_CFGWAITRMT] = 4, | ||
| 639 | [INFINIPATH_IBCS_LT_STATE_CFGIDLE] = 4, | ||
| 640 | [INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN] = 6, | ||
| 641 | [INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT] = 6, | ||
| 642 | [INFINIPATH_IBCS_LT_STATE_RECOVERIDLE] = 6, | ||
| 643 | }; | ||
| 644 | |||
| 645 | static int ipath_query_port(struct ib_device *ibdev, | ||
| 646 | u8 port, struct ib_port_attr *props) | ||
| 647 | { | ||
| 648 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 649 | enum ib_mtu mtu; | ||
| 650 | u16 lid = ipath_layer_get_lid(dev->dd); | ||
| 651 | u64 ibcstat; | ||
| 652 | |||
| 653 | memset(props, 0, sizeof(*props)); | ||
| 654 | props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE); | ||
| 655 | props->lmc = dev->mkeyprot_resv_lmc & 7; | ||
| 656 | props->sm_lid = dev->sm_lid; | ||
| 657 | props->sm_sl = dev->sm_sl; | ||
| 658 | ibcstat = ipath_layer_get_lastibcstat(dev->dd); | ||
| 659 | props->state = ((ibcstat >> 4) & 0x3) + 1; | ||
| 660 | /* See phys_state_show() */ | ||
| 661 | props->phys_state = ipath_cvt_physportstate[ | ||
| 662 | ipath_layer_get_lastibcstat(dev->dd) & 0xf]; | ||
| 663 | props->port_cap_flags = dev->port_cap_flags; | ||
| 664 | props->gid_tbl_len = 1; | ||
| 665 | props->max_msg_sz = 4096; | ||
| 666 | props->pkey_tbl_len = ipath_layer_get_npkeys(dev->dd); | ||
| 667 | props->bad_pkey_cntr = ipath_layer_get_cr_errpkey(dev->dd) - | ||
| 668 | dev->n_pkey_violations; | ||
| 669 | props->qkey_viol_cntr = dev->qkey_violations; | ||
| 670 | props->active_width = IB_WIDTH_4X; | ||
| 671 | /* See rate_show() */ | ||
| 672 | props->active_speed = 1; /* Regular 10Mbs speed. */ | ||
| 673 | props->max_vl_num = 1; /* VLCap = VL0 */ | ||
| 674 | props->init_type_reply = 0; | ||
| 675 | |||
| 676 | props->max_mtu = IB_MTU_4096; | ||
| 677 | switch (ipath_layer_get_ibmtu(dev->dd)) { | ||
| 678 | case 4096: | ||
| 679 | mtu = IB_MTU_4096; | ||
| 680 | break; | ||
| 681 | case 2048: | ||
| 682 | mtu = IB_MTU_2048; | ||
| 683 | break; | ||
| 684 | case 1024: | ||
| 685 | mtu = IB_MTU_1024; | ||
| 686 | break; | ||
| 687 | case 512: | ||
| 688 | mtu = IB_MTU_512; | ||
| 689 | break; | ||
| 690 | case 256: | ||
| 691 | mtu = IB_MTU_256; | ||
| 692 | break; | ||
| 693 | default: | ||
| 694 | mtu = IB_MTU_2048; | ||
| 695 | } | ||
| 696 | props->active_mtu = mtu; | ||
| 697 | props->subnet_timeout = dev->subnet_timeout; | ||
| 698 | |||
| 699 | return 0; | ||
| 700 | } | ||
| 701 | |||
| 702 | static int ipath_modify_device(struct ib_device *device, | ||
| 703 | int device_modify_mask, | ||
| 704 | struct ib_device_modify *device_modify) | ||
| 705 | { | ||
| 706 | int ret; | ||
| 707 | |||
| 708 | if (device_modify_mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | | ||
| 709 | IB_DEVICE_MODIFY_NODE_DESC)) { | ||
| 710 | ret = -EOPNOTSUPP; | ||
| 711 | goto bail; | ||
| 712 | } | ||
| 713 | |||
| 714 | if (device_modify_mask & IB_DEVICE_MODIFY_NODE_DESC) | ||
| 715 | memcpy(device->node_desc, device_modify->node_desc, 64); | ||
| 716 | |||
| 717 | if (device_modify_mask & IB_DEVICE_MODIFY_SYS_IMAGE_GUID) | ||
| 718 | to_idev(device)->sys_image_guid = | ||
| 719 | cpu_to_be64(device_modify->sys_image_guid); | ||
| 720 | |||
| 721 | ret = 0; | ||
| 722 | |||
| 723 | bail: | ||
| 724 | return ret; | ||
| 725 | } | ||
| 726 | |||
| 727 | static int ipath_modify_port(struct ib_device *ibdev, | ||
| 728 | u8 port, int port_modify_mask, | ||
| 729 | struct ib_port_modify *props) | ||
| 730 | { | ||
| 731 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 732 | |||
| 733 | dev->port_cap_flags |= props->set_port_cap_mask; | ||
| 734 | dev->port_cap_flags &= ~props->clr_port_cap_mask; | ||
| 735 | if (port_modify_mask & IB_PORT_SHUTDOWN) | ||
| 736 | ipath_layer_set_linkstate(dev->dd, IPATH_IB_LINKDOWN); | ||
| 737 | if (port_modify_mask & IB_PORT_RESET_QKEY_CNTR) | ||
| 738 | dev->qkey_violations = 0; | ||
| 739 | return 0; | ||
| 740 | } | ||
| 741 | |||
| 742 | static int ipath_query_gid(struct ib_device *ibdev, u8 port, | ||
| 743 | int index, union ib_gid *gid) | ||
| 744 | { | ||
| 745 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 746 | int ret; | ||
| 747 | |||
| 748 | if (index >= 1) { | ||
| 749 | ret = -EINVAL; | ||
| 750 | goto bail; | ||
| 751 | } | ||
| 752 | gid->global.subnet_prefix = dev->gid_prefix; | ||
| 753 | gid->global.interface_id = ipath_layer_get_guid(dev->dd); | ||
| 754 | |||
| 755 | ret = 0; | ||
| 756 | |||
| 757 | bail: | ||
| 758 | return ret; | ||
| 759 | } | ||
| 760 | |||
| 761 | static struct ib_pd *ipath_alloc_pd(struct ib_device *ibdev, | ||
| 762 | struct ib_ucontext *context, | ||
| 763 | struct ib_udata *udata) | ||
| 764 | { | ||
| 765 | struct ipath_pd *pd; | ||
| 766 | struct ib_pd *ret; | ||
| 767 | |||
| 768 | pd = kmalloc(sizeof *pd, GFP_KERNEL); | ||
| 769 | if (!pd) { | ||
| 770 | ret = ERR_PTR(-ENOMEM); | ||
| 771 | goto bail; | ||
| 772 | } | ||
| 773 | |||
| 774 | /* ib_alloc_pd() will initialize pd->ibpd. */ | ||
| 775 | pd->user = udata != NULL; | ||
| 776 | |||
| 777 | ret = &pd->ibpd; | ||
| 778 | |||
| 779 | bail: | ||
| 780 | return ret; | ||
| 781 | } | ||
| 782 | |||
| 783 | static int ipath_dealloc_pd(struct ib_pd *ibpd) | ||
| 784 | { | ||
| 785 | struct ipath_pd *pd = to_ipd(ibpd); | ||
| 786 | |||
| 787 | kfree(pd); | ||
| 788 | |||
| 789 | return 0; | ||
| 790 | } | ||
| 791 | |||
| 792 | /** | ||
| 793 | * ipath_create_ah - create an address handle | ||
| 794 | * @pd: the protection domain | ||
| 795 | * @ah_attr: the attributes of the AH | ||
| 796 | * | ||
| 797 | * This may be called from interrupt context. | ||
| 798 | */ | ||
| 799 | static struct ib_ah *ipath_create_ah(struct ib_pd *pd, | ||
| 800 | struct ib_ah_attr *ah_attr) | ||
| 801 | { | ||
| 802 | struct ipath_ah *ah; | ||
| 803 | struct ib_ah *ret; | ||
| 804 | |||
| 805 | /* A multicast address requires a GRH (see ch. 8.4.1). */ | ||
| 806 | if (ah_attr->dlid >= IPS_MULTICAST_LID_BASE && | ||
| 807 | ah_attr->dlid != IPS_PERMISSIVE_LID && | ||
| 808 | !(ah_attr->ah_flags & IB_AH_GRH)) { | ||
| 809 | ret = ERR_PTR(-EINVAL); | ||
| 810 | goto bail; | ||
| 811 | } | ||
| 812 | |||
| 813 | ah = kmalloc(sizeof *ah, GFP_ATOMIC); | ||
| 814 | if (!ah) { | ||
| 815 | ret = ERR_PTR(-ENOMEM); | ||
| 816 | goto bail; | ||
| 817 | } | ||
| 818 | |||
| 819 | /* ib_create_ah() will initialize ah->ibah. */ | ||
| 820 | ah->attr = *ah_attr; | ||
| 821 | |||
| 822 | ret = &ah->ibah; | ||
| 823 | |||
| 824 | bail: | ||
| 825 | return ret; | ||
| 826 | } | ||
| 827 | |||
| 828 | /** | ||
| 829 | * ipath_destroy_ah - destroy an address handle | ||
| 830 | * @ibah: the AH to destroy | ||
| 831 | * | ||
| 832 | * This may be called from interrupt context. | ||
| 833 | */ | ||
| 834 | static int ipath_destroy_ah(struct ib_ah *ibah) | ||
| 835 | { | ||
| 836 | struct ipath_ah *ah = to_iah(ibah); | ||
| 837 | |||
| 838 | kfree(ah); | ||
| 839 | |||
| 840 | return 0; | ||
| 841 | } | ||
| 842 | |||
| 843 | static int ipath_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr) | ||
| 844 | { | ||
| 845 | struct ipath_ah *ah = to_iah(ibah); | ||
| 846 | |||
| 847 | *ah_attr = ah->attr; | ||
| 848 | |||
| 849 | return 0; | ||
| 850 | } | ||
| 851 | |||
| 852 | static int ipath_query_pkey(struct ib_device *ibdev, u8 port, u16 index, | ||
| 853 | u16 *pkey) | ||
| 854 | { | ||
| 855 | struct ipath_ibdev *dev = to_idev(ibdev); | ||
| 856 | int ret; | ||
| 857 | |||
| 858 | if (index >= ipath_layer_get_npkeys(dev->dd)) { | ||
| 859 | ret = -EINVAL; | ||
| 860 | goto bail; | ||
| 861 | } | ||
| 862 | |||
| 863 | *pkey = ipath_layer_get_pkey(dev->dd, index); | ||
| 864 | ret = 0; | ||
| 865 | |||
| 866 | bail: | ||
| 867 | return ret; | ||
| 868 | } | ||
| 869 | |||
| 870 | |||
| 871 | /** | ||
| 872 | * ipath_alloc_ucontext - allocate a ucontest | ||
| 873 | * @ibdev: the infiniband device | ||
| 874 | * @udata: not used by the InfiniPath driver | ||
| 875 | */ | ||
| 876 | |||
| 877 | static struct ib_ucontext *ipath_alloc_ucontext(struct ib_device *ibdev, | ||
| 878 | struct ib_udata *udata) | ||
| 879 | { | ||
| 880 | struct ipath_ucontext *context; | ||
| 881 | struct ib_ucontext *ret; | ||
| 882 | |||
| 883 | context = kmalloc(sizeof *context, GFP_KERNEL); | ||
| 884 | if (!context) { | ||
| 885 | ret = ERR_PTR(-ENOMEM); | ||
| 886 | goto bail; | ||
| 887 | } | ||
| 888 | |||
| 889 | ret = &context->ibucontext; | ||
| 890 | |||
| 891 | bail: | ||
| 892 | return ret; | ||
| 893 | } | ||
| 894 | |||
| 895 | static int ipath_dealloc_ucontext(struct ib_ucontext *context) | ||
| 896 | { | ||
| 897 | kfree(to_iucontext(context)); | ||
| 898 | return 0; | ||
| 899 | } | ||
| 900 | |||
| 901 | static int ipath_verbs_register_sysfs(struct ib_device *dev); | ||
| 902 | |||
| 903 | /** | ||
| 904 | * ipath_register_ib_device - register our device with the infiniband core | ||
| 905 | * @unit: the device number to register | ||
| 906 | * @dd: the device data structure | ||
| 907 | * Return the allocated ipath_ibdev pointer or NULL on error. | ||
| 908 | */ | ||
| 909 | static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd) | ||
| 910 | { | ||
| 911 | struct ipath_ibdev *idev; | ||
| 912 | struct ib_device *dev; | ||
| 913 | int ret; | ||
| 914 | |||
| 915 | idev = (struct ipath_ibdev *)ib_alloc_device(sizeof *idev); | ||
| 916 | if (idev == NULL) | ||
| 917 | goto bail; | ||
| 918 | |||
| 919 | dev = &idev->ibdev; | ||
| 920 | |||
| 921 | /* Only need to initialize non-zero fields. */ | ||
| 922 | spin_lock_init(&idev->qp_table.lock); | ||
| 923 | spin_lock_init(&idev->lk_table.lock); | ||
| 924 | idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE); | ||
| 925 | /* Set the prefix to the default value (see ch. 4.1.1) */ | ||
| 926 | idev->gid_prefix = __constant_cpu_to_be64(0xfe80000000000000ULL); | ||
| 927 | |||
| 928 | ret = ipath_init_qp_table(idev, ib_ipath_qp_table_size); | ||
| 929 | if (ret) | ||
| 930 | goto err_qp; | ||
| 931 | |||
| 932 | /* | ||
| 933 | * The top ib_ipath_lkey_table_size bits are used to index the | ||
| 934 | * table. The lower 8 bits can be owned by the user (copied from | ||
| 935 | * the LKEY). The remaining bits act as a generation number or tag. | ||
| 936 | */ | ||
| 937 | idev->lk_table.max = 1 << ib_ipath_lkey_table_size; | ||
| 938 | idev->lk_table.table = kzalloc(idev->lk_table.max * | ||
| 939 | sizeof(*idev->lk_table.table), | ||
| 940 | GFP_KERNEL); | ||
| 941 | if (idev->lk_table.table == NULL) { | ||
| 942 | ret = -ENOMEM; | ||
| 943 | goto err_lk; | ||
| 944 | } | ||
| 945 | spin_lock_init(&idev->pending_lock); | ||
| 946 | INIT_LIST_HEAD(&idev->pending[0]); | ||
| 947 | INIT_LIST_HEAD(&idev->pending[1]); | ||
| 948 | INIT_LIST_HEAD(&idev->pending[2]); | ||
| 949 | INIT_LIST_HEAD(&idev->piowait); | ||
| 950 | INIT_LIST_HEAD(&idev->rnrwait); | ||
| 951 | idev->pending_index = 0; | ||
| 952 | idev->port_cap_flags = | ||
| 953 | IB_PORT_SYS_IMAGE_GUID_SUP | IB_PORT_CLIENT_REG_SUP; | ||
| 954 | idev->pma_counter_select[0] = IB_PMA_PORT_XMIT_DATA; | ||
| 955 | idev->pma_counter_select[1] = IB_PMA_PORT_RCV_DATA; | ||
| 956 | idev->pma_counter_select[2] = IB_PMA_PORT_XMIT_PKTS; | ||
| 957 | idev->pma_counter_select[3] = IB_PMA_PORT_RCV_PKTS; | ||
| 958 | idev->pma_counter_select[5] = IB_PMA_PORT_XMIT_WAIT; | ||
| 959 | idev->link_width_enabled = 3; /* 1x or 4x */ | ||
| 960 | |||
| 961 | /* | ||
| 962 | * The system image GUID is supposed to be the same for all | ||
| 963 | * IB HCAs in a single system but since there can be other | ||
| 964 | * device types in the system, we can't be sure this is unique. | ||
| 965 | */ | ||
| 966 | if (!sys_image_guid) | ||
| 967 | sys_image_guid = ipath_layer_get_guid(dd); | ||
| 968 | idev->sys_image_guid = sys_image_guid; | ||
| 969 | idev->ib_unit = unit; | ||
| 970 | idev->dd = dd; | ||
| 971 | |||
| 972 | strlcpy(dev->name, "ipath%d", IB_DEVICE_NAME_MAX); | ||
| 973 | dev->node_guid = ipath_layer_get_guid(dd); | ||
| 974 | dev->uverbs_abi_ver = IPATH_UVERBS_ABI_VERSION; | ||
| 975 | dev->uverbs_cmd_mask = | ||
| 976 | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | | ||
| 977 | (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | | ||
| 978 | (1ull << IB_USER_VERBS_CMD_QUERY_PORT) | | ||
| 979 | (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | | ||
| 980 | (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | | ||
| 981 | (1ull << IB_USER_VERBS_CMD_CREATE_AH) | | ||
| 982 | (1ull << IB_USER_VERBS_CMD_DESTROY_AH) | | ||
| 983 | (1ull << IB_USER_VERBS_CMD_QUERY_AH) | | ||
| 984 | (1ull << IB_USER_VERBS_CMD_REG_MR) | | ||
| 985 | (1ull << IB_USER_VERBS_CMD_DEREG_MR) | | ||
| 986 | (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | | ||
| 987 | (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | | ||
| 988 | (1ull << IB_USER_VERBS_CMD_RESIZE_CQ) | | ||
| 989 | (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | | ||
| 990 | (1ull << IB_USER_VERBS_CMD_POLL_CQ) | | ||
| 991 | (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) | | ||
| 992 | (1ull << IB_USER_VERBS_CMD_CREATE_QP) | | ||
| 993 | (1ull << IB_USER_VERBS_CMD_QUERY_QP) | | ||
| 994 | (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | | ||
| 995 | (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | | ||
| 996 | (1ull << IB_USER_VERBS_CMD_POST_SEND) | | ||
| 997 | (1ull << IB_USER_VERBS_CMD_POST_RECV) | | ||
| 998 | (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | | ||
| 999 | (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) | | ||
| 1000 | (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) | | ||
| 1001 | (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) | | ||
| 1002 | (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) | | ||
| 1003 | (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) | | ||
| 1004 | (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV); | ||
| 1005 | dev->node_type = IB_NODE_CA; | ||
| 1006 | dev->phys_port_cnt = 1; | ||
| 1007 | dev->dma_device = ipath_layer_get_device(dd); | ||
| 1008 | dev->class_dev.dev = dev->dma_device; | ||
| 1009 | dev->query_device = ipath_query_device; | ||
| 1010 | dev->modify_device = ipath_modify_device; | ||
| 1011 | dev->query_port = ipath_query_port; | ||
| 1012 | dev->modify_port = ipath_modify_port; | ||
| 1013 | dev->query_pkey = ipath_query_pkey; | ||
| 1014 | dev->query_gid = ipath_query_gid; | ||
| 1015 | dev->alloc_ucontext = ipath_alloc_ucontext; | ||
| 1016 | dev->dealloc_ucontext = ipath_dealloc_ucontext; | ||
| 1017 | dev->alloc_pd = ipath_alloc_pd; | ||
| 1018 | dev->dealloc_pd = ipath_dealloc_pd; | ||
| 1019 | dev->create_ah = ipath_create_ah; | ||
| 1020 | dev->destroy_ah = ipath_destroy_ah; | ||
| 1021 | dev->query_ah = ipath_query_ah; | ||
| 1022 | dev->create_srq = ipath_create_srq; | ||
| 1023 | dev->modify_srq = ipath_modify_srq; | ||
| 1024 | dev->query_srq = ipath_query_srq; | ||
| 1025 | dev->destroy_srq = ipath_destroy_srq; | ||
| 1026 | dev->create_qp = ipath_create_qp; | ||
| 1027 | dev->modify_qp = ipath_modify_qp; | ||
| 1028 | dev->query_qp = ipath_query_qp; | ||
| 1029 | dev->destroy_qp = ipath_destroy_qp; | ||
| 1030 | dev->post_send = ipath_post_send; | ||
| 1031 | dev->post_recv = ipath_post_receive; | ||
| 1032 | dev->post_srq_recv = ipath_post_srq_receive; | ||
| 1033 | dev->create_cq = ipath_create_cq; | ||
| 1034 | dev->destroy_cq = ipath_destroy_cq; | ||
| 1035 | dev->resize_cq = ipath_resize_cq; | ||
| 1036 | dev->poll_cq = ipath_poll_cq; | ||
| 1037 | dev->req_notify_cq = ipath_req_notify_cq; | ||
| 1038 | dev->get_dma_mr = ipath_get_dma_mr; | ||
| 1039 | dev->reg_phys_mr = ipath_reg_phys_mr; | ||
| 1040 | dev->reg_user_mr = ipath_reg_user_mr; | ||
| 1041 | dev->dereg_mr = ipath_dereg_mr; | ||
| 1042 | dev->alloc_fmr = ipath_alloc_fmr; | ||
| 1043 | dev->map_phys_fmr = ipath_map_phys_fmr; | ||
| 1044 | dev->unmap_fmr = ipath_unmap_fmr; | ||
| 1045 | dev->dealloc_fmr = ipath_dealloc_fmr; | ||
| 1046 | dev->attach_mcast = ipath_multicast_attach; | ||
| 1047 | dev->detach_mcast = ipath_multicast_detach; | ||
| 1048 | dev->process_mad = ipath_process_mad; | ||
| 1049 | |||
| 1050 | snprintf(dev->node_desc, sizeof(dev->node_desc), | ||
| 1051 | IPATH_IDSTR " %s kernel_SMA", system_utsname.nodename); | ||
| 1052 | |||
| 1053 | ret = ib_register_device(dev); | ||
| 1054 | if (ret) | ||
| 1055 | goto err_reg; | ||
| 1056 | |||
| 1057 | if (ipath_verbs_register_sysfs(dev)) | ||
| 1058 | goto err_class; | ||
| 1059 | |||
| 1060 | ipath_layer_enable_timer(dd); | ||
| 1061 | |||
| 1062 | goto bail; | ||
| 1063 | |||
| 1064 | err_class: | ||
| 1065 | ib_unregister_device(dev); | ||
| 1066 | err_reg: | ||
| 1067 | kfree(idev->lk_table.table); | ||
| 1068 | err_lk: | ||
| 1069 | kfree(idev->qp_table.table); | ||
| 1070 | err_qp: | ||
| 1071 | ib_dealloc_device(dev); | ||
| 1072 | _VERBS_ERROR("ib_ipath%d cannot register verbs (%d)!\n", | ||
| 1073 | unit, -ret); | ||
| 1074 | idev = NULL; | ||
| 1075 | |||
| 1076 | bail: | ||
| 1077 | return idev; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | static void ipath_unregister_ib_device(void *arg) | ||
| 1081 | { | ||
| 1082 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; | ||
| 1083 | struct ib_device *ibdev = &dev->ibdev; | ||
| 1084 | |||
| 1085 | ipath_layer_disable_timer(dev->dd); | ||
| 1086 | |||
| 1087 | ib_unregister_device(ibdev); | ||
| 1088 | |||
| 1089 | if (!list_empty(&dev->pending[0]) || | ||
| 1090 | !list_empty(&dev->pending[1]) || | ||
| 1091 | !list_empty(&dev->pending[2])) | ||
| 1092 | _VERBS_ERROR("ipath%d pending list not empty!\n", | ||
| 1093 | dev->ib_unit); | ||
| 1094 | if (!list_empty(&dev->piowait)) | ||
| 1095 | _VERBS_ERROR("ipath%d piowait list not empty!\n", | ||
| 1096 | dev->ib_unit); | ||
| 1097 | if (!list_empty(&dev->rnrwait)) | ||
| 1098 | _VERBS_ERROR("ipath%d rnrwait list not empty!\n", | ||
| 1099 | dev->ib_unit); | ||
| 1100 | if (!ipath_mcast_tree_empty()) | ||
| 1101 | _VERBS_ERROR("ipath%d multicast table memory leak!\n", | ||
| 1102 | dev->ib_unit); | ||
| 1103 | /* | ||
| 1104 | * Note that ipath_unregister_ib_device() can be called before all | ||
| 1105 | * the QPs are destroyed! | ||
| 1106 | */ | ||
| 1107 | ipath_free_all_qps(&dev->qp_table); | ||
| 1108 | kfree(dev->qp_table.table); | ||
| 1109 | kfree(dev->lk_table.table); | ||
| 1110 | ib_dealloc_device(ibdev); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | int __init ipath_verbs_init(void) | ||
| 1114 | { | ||
| 1115 | return ipath_verbs_register(ipath_register_ib_device, | ||
| 1116 | ipath_unregister_ib_device, | ||
| 1117 | ipath_ib_piobufavail, ipath_ib_rcv, | ||
| 1118 | ipath_ib_timer); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | void __exit ipath_verbs_cleanup(void) | ||
| 1122 | { | ||
| 1123 | ipath_verbs_unregister(); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | static ssize_t show_rev(struct class_device *cdev, char *buf) | ||
| 1127 | { | ||
| 1128 | struct ipath_ibdev *dev = | ||
| 1129 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | ||
| 1130 | int vendor, boardrev, majrev, minrev; | ||
| 1131 | |||
| 1132 | ipath_layer_query_device(dev->dd, &vendor, &boardrev, | ||
| 1133 | &majrev, &minrev); | ||
| 1134 | return sprintf(buf, "%d.%d\n", majrev, minrev); | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | static ssize_t show_hca(struct class_device *cdev, char *buf) | ||
| 1138 | { | ||
| 1139 | struct ipath_ibdev *dev = | ||
| 1140 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | ||
| 1141 | int ret; | ||
| 1142 | |||
| 1143 | ret = ipath_layer_get_boardname(dev->dd, buf, 128); | ||
| 1144 | if (ret < 0) | ||
| 1145 | goto bail; | ||
| 1146 | strcat(buf, "\n"); | ||
| 1147 | ret = strlen(buf); | ||
| 1148 | |||
| 1149 | bail: | ||
| 1150 | return ret; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | static ssize_t show_stats(struct class_device *cdev, char *buf) | ||
| 1154 | { | ||
| 1155 | struct ipath_ibdev *dev = | ||
| 1156 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | ||
| 1157 | int i; | ||
| 1158 | int len; | ||
| 1159 | |||
| 1160 | len = sprintf(buf, | ||
| 1161 | "RC resends %d\n" | ||
| 1162 | "RC QACKs %d\n" | ||
| 1163 | "RC ACKs %d\n" | ||
| 1164 | "RC SEQ NAKs %d\n" | ||
| 1165 | "RC RDMA seq %d\n" | ||
| 1166 | "RC RNR NAKs %d\n" | ||
| 1167 | "RC OTH NAKs %d\n" | ||
| 1168 | "RC timeouts %d\n" | ||
| 1169 | "RC RDMA dup %d\n" | ||
| 1170 | "piobuf wait %d\n" | ||
| 1171 | "no piobuf %d\n" | ||
| 1172 | "PKT drops %d\n" | ||
| 1173 | "WQE errs %d\n", | ||
| 1174 | dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks, | ||
| 1175 | dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks, | ||
| 1176 | dev->n_other_naks, dev->n_timeouts, | ||
| 1177 | dev->n_rdma_dup_busy, dev->n_piowait, | ||
| 1178 | dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs); | ||
| 1179 | for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) { | ||
| 1180 | const struct ipath_opcode_stats *si = &dev->opstats[i]; | ||
| 1181 | |||
| 1182 | if (!si->n_packets && !si->n_bytes) | ||
| 1183 | continue; | ||
| 1184 | len += sprintf(buf + len, "%02x %llu/%llu\n", i, | ||
| 1185 | (unsigned long long) si->n_packets, | ||
| 1186 | (unsigned long long) si->n_bytes); | ||
| 1187 | } | ||
| 1188 | return len; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); | ||
| 1192 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); | ||
| 1193 | static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL); | ||
| 1194 | static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL); | ||
| 1195 | |||
| 1196 | static struct class_device_attribute *ipath_class_attributes[] = { | ||
| 1197 | &class_device_attr_hw_rev, | ||
| 1198 | &class_device_attr_hca_type, | ||
| 1199 | &class_device_attr_board_id, | ||
| 1200 | &class_device_attr_stats | ||
| 1201 | }; | ||
| 1202 | |||
| 1203 | static int ipath_verbs_register_sysfs(struct ib_device *dev) | ||
| 1204 | { | ||
| 1205 | int i; | ||
| 1206 | int ret; | ||
| 1207 | |||
| 1208 | for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i) | ||
| 1209 | if (class_device_create_file(&dev->class_dev, | ||
| 1210 | ipath_class_attributes[i])) { | ||
| 1211 | ret = 1; | ||
| 1212 | goto bail; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | ret = 0; | ||
| 1216 | |||
| 1217 | bail: | ||
| 1218 | return ret; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | module_init(ipath_verbs_init); | ||
| 1222 | module_exit(ipath_verbs_cleanup); | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h new file mode 100644 index 000000000000..b824632b2a8c --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
| @@ -0,0 +1,697 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef IPATH_VERBS_H | ||
| 34 | #define IPATH_VERBS_H | ||
| 35 | |||
| 36 | #include <linux/types.h> | ||
| 37 | #include <linux/spinlock.h> | ||
| 38 | #include <linux/kernel.h> | ||
| 39 | #include <linux/interrupt.h> | ||
| 40 | #include <rdma/ib_pack.h> | ||
| 41 | |||
| 42 | #include "ipath_layer.h" | ||
| 43 | #include "verbs_debug.h" | ||
| 44 | |||
| 45 | #define QPN_MAX (1 << 24) | ||
| 46 | #define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Increment this value if any changes that break userspace ABI | ||
| 50 | * compatibility are made. | ||
| 51 | */ | ||
| 52 | #define IPATH_UVERBS_ABI_VERSION 1 | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Define an ib_cq_notify value that is not valid so we know when CQ | ||
| 56 | * notifications are armed. | ||
| 57 | */ | ||
| 58 | #define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) | ||
| 59 | |||
| 60 | #define IB_RNR_NAK 0x20 | ||
| 61 | #define IB_NAK_PSN_ERROR 0x60 | ||
| 62 | #define IB_NAK_INVALID_REQUEST 0x61 | ||
| 63 | #define IB_NAK_REMOTE_ACCESS_ERROR 0x62 | ||
| 64 | #define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 | ||
| 65 | #define IB_NAK_INVALID_RD_REQUEST 0x64 | ||
| 66 | |||
| 67 | #define IPATH_POST_SEND_OK 0x01 | ||
| 68 | #define IPATH_POST_RECV_OK 0x02 | ||
| 69 | #define IPATH_PROCESS_RECV_OK 0x04 | ||
| 70 | #define IPATH_PROCESS_SEND_OK 0x08 | ||
| 71 | |||
| 72 | /* IB Performance Manager status values */ | ||
| 73 | #define IB_PMA_SAMPLE_STATUS_DONE 0x00 | ||
| 74 | #define IB_PMA_SAMPLE_STATUS_STARTED 0x01 | ||
| 75 | #define IB_PMA_SAMPLE_STATUS_RUNNING 0x02 | ||
| 76 | |||
| 77 | /* Mandatory IB performance counter select values. */ | ||
| 78 | #define IB_PMA_PORT_XMIT_DATA __constant_htons(0x0001) | ||
| 79 | #define IB_PMA_PORT_RCV_DATA __constant_htons(0x0002) | ||
| 80 | #define IB_PMA_PORT_XMIT_PKTS __constant_htons(0x0003) | ||
| 81 | #define IB_PMA_PORT_RCV_PKTS __constant_htons(0x0004) | ||
| 82 | #define IB_PMA_PORT_XMIT_WAIT __constant_htons(0x0005) | ||
| 83 | |||
| 84 | struct ib_reth { | ||
| 85 | __be64 vaddr; | ||
| 86 | __be32 rkey; | ||
| 87 | __be32 length; | ||
| 88 | } __attribute__ ((packed)); | ||
| 89 | |||
| 90 | struct ib_atomic_eth { | ||
| 91 | __be64 vaddr; | ||
| 92 | __be32 rkey; | ||
| 93 | __be64 swap_data; | ||
| 94 | __be64 compare_data; | ||
| 95 | } __attribute__ ((packed)); | ||
| 96 | |||
| 97 | struct ipath_other_headers { | ||
| 98 | __be32 bth[3]; | ||
| 99 | union { | ||
| 100 | struct { | ||
| 101 | __be32 deth[2]; | ||
| 102 | __be32 imm_data; | ||
| 103 | } ud; | ||
| 104 | struct { | ||
| 105 | struct ib_reth reth; | ||
| 106 | __be32 imm_data; | ||
| 107 | } rc; | ||
| 108 | struct { | ||
| 109 | __be32 aeth; | ||
| 110 | __be64 atomic_ack_eth; | ||
| 111 | } at; | ||
| 112 | __be32 imm_data; | ||
| 113 | __be32 aeth; | ||
| 114 | struct ib_atomic_eth atomic_eth; | ||
| 115 | } u; | ||
| 116 | } __attribute__ ((packed)); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Note that UD packets with a GRH header are 8+40+12+8 = 68 bytes | ||
| 120 | * long (72 w/ imm_data). Only the first 56 bytes of the IB header | ||
| 121 | * will be in the eager header buffer. The remaining 12 or 16 bytes | ||
| 122 | * are in the data buffer. | ||
| 123 | */ | ||
| 124 | struct ipath_ib_header { | ||
| 125 | __be16 lrh[4]; | ||
| 126 | union { | ||
| 127 | struct { | ||
| 128 | struct ib_grh grh; | ||
| 129 | struct ipath_other_headers oth; | ||
| 130 | } l; | ||
| 131 | struct ipath_other_headers oth; | ||
| 132 | } u; | ||
| 133 | } __attribute__ ((packed)); | ||
| 134 | |||
| 135 | /* | ||
| 136 | * There is one struct ipath_mcast for each multicast GID. | ||
| 137 | * All attached QPs are then stored as a list of | ||
| 138 | * struct ipath_mcast_qp. | ||
| 139 | */ | ||
| 140 | struct ipath_mcast_qp { | ||
| 141 | struct list_head list; | ||
| 142 | struct ipath_qp *qp; | ||
| 143 | }; | ||
| 144 | |||
| 145 | struct ipath_mcast { | ||
| 146 | struct rb_node rb_node; | ||
| 147 | union ib_gid mgid; | ||
| 148 | struct list_head qp_list; | ||
| 149 | wait_queue_head_t wait; | ||
| 150 | atomic_t refcount; | ||
| 151 | }; | ||
| 152 | |||
| 153 | /* Memory region */ | ||
| 154 | struct ipath_mr { | ||
| 155 | struct ib_mr ibmr; | ||
| 156 | struct ipath_mregion mr; /* must be last */ | ||
| 157 | }; | ||
| 158 | |||
| 159 | /* Fast memory region */ | ||
| 160 | struct ipath_fmr { | ||
| 161 | struct ib_fmr ibfmr; | ||
| 162 | u8 page_shift; | ||
| 163 | struct ipath_mregion mr; /* must be last */ | ||
| 164 | }; | ||
| 165 | |||
| 166 | /* Protection domain */ | ||
| 167 | struct ipath_pd { | ||
| 168 | struct ib_pd ibpd; | ||
| 169 | int user; /* non-zero if created from user space */ | ||
| 170 | }; | ||
| 171 | |||
| 172 | /* Address Handle */ | ||
| 173 | struct ipath_ah { | ||
| 174 | struct ib_ah ibah; | ||
| 175 | struct ib_ah_attr attr; | ||
| 176 | }; | ||
| 177 | |||
| 178 | /* | ||
| 179 | * Quick description of our CQ/QP locking scheme: | ||
| 180 | * | ||
| 181 | * We have one global lock that protects dev->cq/qp_table. Each | ||
| 182 | * struct ipath_cq/qp also has its own lock. An individual qp lock | ||
| 183 | * may be taken inside of an individual cq lock. Both cqs attached to | ||
| 184 | * a qp may be locked, with the send cq locked first. No other | ||
| 185 | * nesting should be done. | ||
| 186 | * | ||
| 187 | * Each struct ipath_cq/qp also has an atomic_t ref count. The | ||
| 188 | * pointer from the cq/qp_table to the struct counts as one reference. | ||
| 189 | * This reference also is good for access through the consumer API, so | ||
| 190 | * modifying the CQ/QP etc doesn't need to take another reference. | ||
| 191 | * Access because of a completion being polled does need a reference. | ||
| 192 | * | ||
| 193 | * Finally, each struct ipath_cq/qp has a wait_queue_head_t for the | ||
| 194 | * destroy function to sleep on. | ||
| 195 | * | ||
| 196 | * This means that access from the consumer API requires nothing but | ||
| 197 | * taking the struct's lock. | ||
| 198 | * | ||
| 199 | * Access because of a completion event should go as follows: | ||
| 200 | * - lock cq/qp_table and look up struct | ||
| 201 | * - increment ref count in struct | ||
| 202 | * - drop cq/qp_table lock | ||
| 203 | * - lock struct, do your thing, and unlock struct | ||
| 204 | * - decrement ref count; if zero, wake up waiters | ||
| 205 | * | ||
| 206 | * To destroy a CQ/QP, we can do the following: | ||
| 207 | * - lock cq/qp_table, remove pointer, unlock cq/qp_table lock | ||
| 208 | * - decrement ref count | ||
| 209 | * - wait_event until ref count is zero | ||
| 210 | * | ||
| 211 | * It is the consumer's responsibilty to make sure that no QP | ||
| 212 | * operations (WQE posting or state modification) are pending when the | ||
| 213 | * QP is destroyed. Also, the consumer must make sure that calls to | ||
| 214 | * qp_modify are serialized. | ||
| 215 | * | ||
| 216 | * Possible optimizations (wait for profile data to see if/where we | ||
| 217 | * have locks bouncing between CPUs): | ||
| 218 | * - split cq/qp table lock into n separate (cache-aligned) locks, | ||
| 219 | * indexed (say) by the page in the table | ||
| 220 | */ | ||
| 221 | |||
| 222 | struct ipath_cq { | ||
| 223 | struct ib_cq ibcq; | ||
| 224 | struct tasklet_struct comptask; | ||
| 225 | spinlock_t lock; | ||
| 226 | u8 notify; | ||
| 227 | u8 triggered; | ||
| 228 | u32 head; /* new records added to the head */ | ||
| 229 | u32 tail; /* poll_cq() reads from here. */ | ||
| 230 | struct ib_wc *queue; /* this is actually ibcq.cqe + 1 */ | ||
| 231 | }; | ||
| 232 | |||
| 233 | /* | ||
| 234 | * Send work request queue entry. | ||
| 235 | * The size of the sg_list is determined when the QP is created and stored | ||
| 236 | * in qp->s_max_sge. | ||
| 237 | */ | ||
| 238 | struct ipath_swqe { | ||
| 239 | struct ib_send_wr wr; /* don't use wr.sg_list */ | ||
| 240 | u32 psn; /* first packet sequence number */ | ||
| 241 | u32 lpsn; /* last packet sequence number */ | ||
| 242 | u32 ssn; /* send sequence number */ | ||
| 243 | u32 length; /* total length of data in sg_list */ | ||
| 244 | struct ipath_sge sg_list[0]; | ||
| 245 | }; | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Receive work request queue entry. | ||
| 249 | * The size of the sg_list is determined when the QP is created and stored | ||
| 250 | * in qp->r_max_sge. | ||
| 251 | */ | ||
| 252 | struct ipath_rwqe { | ||
| 253 | u64 wr_id; | ||
| 254 | u32 length; /* total length of data in sg_list */ | ||
| 255 | u8 num_sge; | ||
| 256 | struct ipath_sge sg_list[0]; | ||
| 257 | }; | ||
| 258 | |||
| 259 | struct ipath_rq { | ||
| 260 | spinlock_t lock; | ||
| 261 | u32 head; /* new work requests posted to the head */ | ||
| 262 | u32 tail; /* receives pull requests from here. */ | ||
| 263 | u32 size; /* size of RWQE array */ | ||
| 264 | u8 max_sge; | ||
| 265 | struct ipath_rwqe *wq; /* RWQE array */ | ||
| 266 | }; | ||
| 267 | |||
| 268 | struct ipath_srq { | ||
| 269 | struct ib_srq ibsrq; | ||
| 270 | struct ipath_rq rq; | ||
| 271 | /* send signal when number of RWQEs < limit */ | ||
| 272 | u32 limit; | ||
| 273 | }; | ||
| 274 | |||
| 275 | /* | ||
| 276 | * Variables prefixed with s_ are for the requester (sender). | ||
| 277 | * Variables prefixed with r_ are for the responder (receiver). | ||
| 278 | * Variables prefixed with ack_ are for responder replies. | ||
| 279 | * | ||
| 280 | * Common variables are protected by both r_rq.lock and s_lock in that order | ||
| 281 | * which only happens in modify_qp() or changing the QP 'state'. | ||
| 282 | */ | ||
| 283 | struct ipath_qp { | ||
| 284 | struct ib_qp ibqp; | ||
| 285 | struct ipath_qp *next; /* link list for QPN hash table */ | ||
| 286 | struct list_head piowait; /* link for wait PIO buf */ | ||
| 287 | struct list_head timerwait; /* link for waiting for timeouts */ | ||
| 288 | struct ib_ah_attr remote_ah_attr; | ||
| 289 | struct ipath_ib_header s_hdr; /* next packet header to send */ | ||
| 290 | atomic_t refcount; | ||
| 291 | wait_queue_head_t wait; | ||
| 292 | struct tasklet_struct s_task; | ||
| 293 | struct ipath_sge_state *s_cur_sge; | ||
| 294 | struct ipath_sge_state s_sge; /* current send request data */ | ||
| 295 | /* current RDMA read send data */ | ||
| 296 | struct ipath_sge_state s_rdma_sge; | ||
| 297 | struct ipath_sge_state r_sge; /* current receive data */ | ||
| 298 | spinlock_t s_lock; | ||
| 299 | unsigned long s_flags; | ||
| 300 | u32 s_hdrwords; /* size of s_hdr in 32 bit words */ | ||
| 301 | u32 s_cur_size; /* size of send packet in bytes */ | ||
| 302 | u32 s_len; /* total length of s_sge */ | ||
| 303 | u32 s_rdma_len; /* total length of s_rdma_sge */ | ||
| 304 | u32 s_next_psn; /* PSN for next request */ | ||
| 305 | u32 s_last_psn; /* last response PSN processed */ | ||
| 306 | u32 s_psn; /* current packet sequence number */ | ||
| 307 | u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ | ||
| 308 | u32 s_ack_psn; /* PSN for next ACK or RDMA_READ */ | ||
| 309 | u64 s_ack_atomic; /* data for atomic ACK */ | ||
| 310 | u64 r_wr_id; /* ID for current receive WQE */ | ||
| 311 | u64 r_atomic_data; /* data for last atomic op */ | ||
| 312 | u32 r_atomic_psn; /* PSN of last atomic op */ | ||
| 313 | u32 r_len; /* total length of r_sge */ | ||
| 314 | u32 r_rcv_len; /* receive data len processed */ | ||
| 315 | u32 r_psn; /* expected rcv packet sequence number */ | ||
| 316 | u8 state; /* QP state */ | ||
| 317 | u8 s_state; /* opcode of last packet sent */ | ||
| 318 | u8 s_ack_state; /* opcode of packet to ACK */ | ||
| 319 | u8 s_nak_state; /* non-zero if NAK is pending */ | ||
| 320 | u8 r_state; /* opcode of last packet received */ | ||
| 321 | u8 r_reuse_sge; /* for UC receive errors */ | ||
| 322 | u8 r_sge_inx; /* current index into sg_list */ | ||
| 323 | u8 s_max_sge; /* size of s_wq->sg_list */ | ||
| 324 | u8 qp_access_flags; | ||
| 325 | u8 s_retry_cnt; /* number of times to retry */ | ||
| 326 | u8 s_rnr_retry_cnt; | ||
| 327 | u8 s_min_rnr_timer; | ||
| 328 | u8 s_retry; /* requester retry counter */ | ||
| 329 | u8 s_rnr_retry; /* requester RNR retry counter */ | ||
| 330 | u8 s_pkey_index; /* PKEY index to use */ | ||
| 331 | enum ib_mtu path_mtu; | ||
| 332 | atomic_t msn; /* message sequence number */ | ||
| 333 | u32 remote_qpn; | ||
| 334 | u32 qkey; /* QKEY for this QP (for UD or RD) */ | ||
| 335 | u32 s_size; /* send work queue size */ | ||
| 336 | u32 s_head; /* new entries added here */ | ||
| 337 | u32 s_tail; /* next entry to process */ | ||
| 338 | u32 s_cur; /* current work queue entry */ | ||
| 339 | u32 s_last; /* last un-ACK'ed entry */ | ||
| 340 | u32 s_ssn; /* SSN of tail entry */ | ||
| 341 | u32 s_lsn; /* limit sequence number (credit) */ | ||
| 342 | struct ipath_swqe *s_wq; /* send work queue */ | ||
| 343 | struct ipath_rq r_rq; /* receive work queue */ | ||
| 344 | }; | ||
| 345 | |||
| 346 | /* | ||
| 347 | * Bit definitions for s_flags. | ||
| 348 | */ | ||
| 349 | #define IPATH_S_BUSY 0 | ||
| 350 | #define IPATH_S_SIGNAL_REQ_WR 1 | ||
| 351 | |||
| 352 | /* | ||
| 353 | * Since struct ipath_swqe is not a fixed size, we can't simply index into | ||
| 354 | * struct ipath_qp.s_wq. This function does the array index computation. | ||
| 355 | */ | ||
| 356 | static inline struct ipath_swqe *get_swqe_ptr(struct ipath_qp *qp, | ||
| 357 | unsigned n) | ||
| 358 | { | ||
| 359 | return (struct ipath_swqe *)((char *)qp->s_wq + | ||
| 360 | (sizeof(struct ipath_swqe) + | ||
| 361 | qp->s_max_sge * | ||
| 362 | sizeof(struct ipath_sge)) * n); | ||
| 363 | } | ||
| 364 | |||
| 365 | /* | ||
| 366 | * Since struct ipath_rwqe is not a fixed size, we can't simply index into | ||
| 367 | * struct ipath_rq.wq. This function does the array index computation. | ||
| 368 | */ | ||
| 369 | static inline struct ipath_rwqe *get_rwqe_ptr(struct ipath_rq *rq, | ||
| 370 | unsigned n) | ||
| 371 | { | ||
| 372 | return (struct ipath_rwqe *) | ||
| 373 | ((char *) rq->wq + | ||
| 374 | (sizeof(struct ipath_rwqe) + | ||
| 375 | rq->max_sge * sizeof(struct ipath_sge)) * n); | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * QPN-map pages start out as NULL, they get allocated upon | ||
| 380 | * first use and are never deallocated. This way, | ||
| 381 | * large bitmaps are not allocated unless large numbers of QPs are used. | ||
| 382 | */ | ||
| 383 | struct qpn_map { | ||
| 384 | atomic_t n_free; | ||
| 385 | void *page; | ||
| 386 | }; | ||
| 387 | |||
| 388 | struct ipath_qp_table { | ||
| 389 | spinlock_t lock; | ||
| 390 | u32 last; /* last QP number allocated */ | ||
| 391 | u32 max; /* size of the hash table */ | ||
| 392 | u32 nmaps; /* size of the map table */ | ||
| 393 | struct ipath_qp **table; | ||
| 394 | /* bit map of free numbers */ | ||
| 395 | struct qpn_map map[QPNMAP_ENTRIES]; | ||
| 396 | }; | ||
| 397 | |||
| 398 | struct ipath_lkey_table { | ||
| 399 | spinlock_t lock; | ||
| 400 | u32 next; /* next unused index (speeds search) */ | ||
| 401 | u32 gen; /* generation count */ | ||
| 402 | u32 max; /* size of the table */ | ||
| 403 | struct ipath_mregion **table; | ||
| 404 | }; | ||
| 405 | |||
| 406 | struct ipath_opcode_stats { | ||
| 407 | u64 n_packets; /* number of packets */ | ||
| 408 | u64 n_bytes; /* total number of bytes */ | ||
| 409 | }; | ||
| 410 | |||
| 411 | struct ipath_ibdev { | ||
| 412 | struct ib_device ibdev; | ||
| 413 | struct list_head dev_list; | ||
| 414 | struct ipath_devdata *dd; | ||
| 415 | int ib_unit; /* This is the device number */ | ||
| 416 | u16 sm_lid; /* in host order */ | ||
| 417 | u8 sm_sl; | ||
| 418 | u8 mkeyprot_resv_lmc; | ||
| 419 | /* non-zero when timer is set */ | ||
| 420 | unsigned long mkey_lease_timeout; | ||
| 421 | |||
| 422 | /* The following fields are really per port. */ | ||
| 423 | struct ipath_qp_table qp_table; | ||
| 424 | struct ipath_lkey_table lk_table; | ||
| 425 | struct list_head pending[3]; /* FIFO of QPs waiting for ACKs */ | ||
| 426 | struct list_head piowait; /* list for wait PIO buf */ | ||
| 427 | /* list of QPs waiting for RNR timer */ | ||
| 428 | struct list_head rnrwait; | ||
| 429 | spinlock_t pending_lock; | ||
| 430 | __be64 sys_image_guid; /* in network order */ | ||
| 431 | __be64 gid_prefix; /* in network order */ | ||
| 432 | __be64 mkey; | ||
| 433 | u64 ipath_sword; /* total dwords sent (sample result) */ | ||
| 434 | u64 ipath_rword; /* total dwords received (sample result) */ | ||
| 435 | u64 ipath_spkts; /* total packets sent (sample result) */ | ||
| 436 | u64 ipath_rpkts; /* total packets received (sample result) */ | ||
| 437 | /* # of ticks no data sent (sample result) */ | ||
| 438 | u64 ipath_xmit_wait; | ||
| 439 | u64 rcv_errors; /* # of packets with SW detected rcv errs */ | ||
| 440 | u64 n_unicast_xmit; /* total unicast packets sent */ | ||
| 441 | u64 n_unicast_rcv; /* total unicast packets received */ | ||
| 442 | u64 n_multicast_xmit; /* total multicast packets sent */ | ||
| 443 | u64 n_multicast_rcv; /* total multicast packets received */ | ||
| 444 | u64 n_symbol_error_counter; /* starting count for PMA */ | ||
| 445 | u64 n_link_error_recovery_counter; /* starting count for PMA */ | ||
| 446 | u64 n_link_downed_counter; /* starting count for PMA */ | ||
| 447 | u64 n_port_rcv_errors; /* starting count for PMA */ | ||
| 448 | u64 n_port_rcv_remphys_errors; /* starting count for PMA */ | ||
| 449 | u64 n_port_xmit_discards; /* starting count for PMA */ | ||
| 450 | u64 n_port_xmit_data; /* starting count for PMA */ | ||
| 451 | u64 n_port_rcv_data; /* starting count for PMA */ | ||
| 452 | u64 n_port_xmit_packets; /* starting count for PMA */ | ||
| 453 | u64 n_port_rcv_packets; /* starting count for PMA */ | ||
| 454 | u32 n_pkey_violations; /* starting count for PMA */ | ||
| 455 | u32 n_rc_resends; | ||
| 456 | u32 n_rc_acks; | ||
| 457 | u32 n_rc_qacks; | ||
| 458 | u32 n_seq_naks; | ||
| 459 | u32 n_rdma_seq; | ||
| 460 | u32 n_rnr_naks; | ||
| 461 | u32 n_other_naks; | ||
| 462 | u32 n_timeouts; | ||
| 463 | u32 n_pkt_drops; | ||
| 464 | u32 n_wqe_errs; | ||
| 465 | u32 n_rdma_dup_busy; | ||
| 466 | u32 n_piowait; | ||
| 467 | u32 n_no_piobuf; | ||
| 468 | u32 port_cap_flags; | ||
| 469 | u32 pma_sample_start; | ||
| 470 | u32 pma_sample_interval; | ||
| 471 | __be16 pma_counter_select[5]; | ||
| 472 | u16 pma_tag; | ||
| 473 | u16 qkey_violations; | ||
| 474 | u16 mkey_violations; | ||
| 475 | u16 mkey_lease_period; | ||
| 476 | u16 pending_index; /* which pending queue is active */ | ||
| 477 | u8 pma_sample_status; | ||
| 478 | u8 subnet_timeout; | ||
| 479 | u8 link_width_enabled; | ||
| 480 | u8 vl_high_limit; | ||
| 481 | struct ipath_opcode_stats opstats[128]; | ||
| 482 | }; | ||
| 483 | |||
| 484 | struct ipath_ucontext { | ||
| 485 | struct ib_ucontext ibucontext; | ||
| 486 | }; | ||
| 487 | |||
| 488 | static inline struct ipath_mr *to_imr(struct ib_mr *ibmr) | ||
| 489 | { | ||
| 490 | return container_of(ibmr, struct ipath_mr, ibmr); | ||
| 491 | } | ||
| 492 | |||
| 493 | static inline struct ipath_fmr *to_ifmr(struct ib_fmr *ibfmr) | ||
| 494 | { | ||
| 495 | return container_of(ibfmr, struct ipath_fmr, ibfmr); | ||
| 496 | } | ||
| 497 | |||
| 498 | static inline struct ipath_pd *to_ipd(struct ib_pd *ibpd) | ||
| 499 | { | ||
| 500 | return container_of(ibpd, struct ipath_pd, ibpd); | ||
| 501 | } | ||
| 502 | |||
| 503 | static inline struct ipath_ah *to_iah(struct ib_ah *ibah) | ||
| 504 | { | ||
| 505 | return container_of(ibah, struct ipath_ah, ibah); | ||
| 506 | } | ||
| 507 | |||
| 508 | static inline struct ipath_cq *to_icq(struct ib_cq *ibcq) | ||
| 509 | { | ||
| 510 | return container_of(ibcq, struct ipath_cq, ibcq); | ||
| 511 | } | ||
| 512 | |||
| 513 | static inline struct ipath_srq *to_isrq(struct ib_srq *ibsrq) | ||
| 514 | { | ||
| 515 | return container_of(ibsrq, struct ipath_srq, ibsrq); | ||
| 516 | } | ||
| 517 | |||
| 518 | static inline struct ipath_qp *to_iqp(struct ib_qp *ibqp) | ||
| 519 | { | ||
| 520 | return container_of(ibqp, struct ipath_qp, ibqp); | ||
| 521 | } | ||
| 522 | |||
| 523 | static inline struct ipath_ibdev *to_idev(struct ib_device *ibdev) | ||
| 524 | { | ||
| 525 | return container_of(ibdev, struct ipath_ibdev, ibdev); | ||
| 526 | } | ||
| 527 | |||
| 528 | int ipath_process_mad(struct ib_device *ibdev, | ||
| 529 | int mad_flags, | ||
| 530 | u8 port_num, | ||
| 531 | struct ib_wc *in_wc, | ||
| 532 | struct ib_grh *in_grh, | ||
| 533 | struct ib_mad *in_mad, struct ib_mad *out_mad); | ||
| 534 | |||
| 535 | static inline struct ipath_ucontext *to_iucontext(struct ib_ucontext | ||
| 536 | *ibucontext) | ||
| 537 | { | ||
| 538 | return container_of(ibucontext, struct ipath_ucontext, ibucontext); | ||
| 539 | } | ||
| 540 | |||
| 541 | /* | ||
| 542 | * Compare the lower 24 bits of the two values. | ||
| 543 | * Returns an integer <, ==, or > than zero. | ||
| 544 | */ | ||
| 545 | static inline int ipath_cmp24(u32 a, u32 b) | ||
| 546 | { | ||
| 547 | return (((int) a) - ((int) b)) << 8; | ||
| 548 | } | ||
| 549 | |||
| 550 | struct ipath_mcast *ipath_mcast_find(union ib_gid *mgid); | ||
| 551 | |||
| 552 | int ipath_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); | ||
| 553 | |||
| 554 | int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); | ||
| 555 | |||
| 556 | int ipath_mcast_tree_empty(void); | ||
| 557 | |||
| 558 | __be32 ipath_compute_aeth(struct ipath_qp *qp); | ||
| 559 | |||
| 560 | struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn); | ||
| 561 | |||
| 562 | struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | ||
| 563 | struct ib_qp_init_attr *init_attr, | ||
| 564 | struct ib_udata *udata); | ||
| 565 | |||
| 566 | int ipath_destroy_qp(struct ib_qp *ibqp); | ||
| 567 | |||
| 568 | int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 569 | int attr_mask); | ||
| 570 | |||
| 571 | int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | ||
| 572 | int attr_mask, struct ib_qp_init_attr *init_attr); | ||
| 573 | |||
| 574 | void ipath_free_all_qps(struct ipath_qp_table *qpt); | ||
| 575 | |||
| 576 | int ipath_init_qp_table(struct ipath_ibdev *idev, int size); | ||
| 577 | |||
| 578 | void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); | ||
| 579 | |||
| 580 | void ipath_error_qp(struct ipath_qp *qp); | ||
| 581 | |||
| 582 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); | ||
| 583 | |||
| 584 | void ipath_do_rc_send(unsigned long data); | ||
| 585 | |||
| 586 | void ipath_do_uc_send(unsigned long data); | ||
| 587 | |||
| 588 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | ||
| 589 | |||
| 590 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | ||
| 591 | u32 len, u64 vaddr, u32 rkey, int acc); | ||
| 592 | |||
| 593 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | ||
| 594 | struct ib_sge *sge, int acc); | ||
| 595 | |||
| 596 | void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); | ||
| 597 | |||
| 598 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); | ||
| 599 | |||
| 600 | int ipath_post_rc_send(struct ipath_qp *qp, struct ib_send_wr *wr); | ||
| 601 | |||
| 602 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 603 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); | ||
| 604 | |||
| 605 | void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 606 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); | ||
| 607 | |||
| 608 | void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc); | ||
| 609 | |||
| 610 | void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, | ||
| 611 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc); | ||
| 612 | |||
| 613 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr); | ||
| 614 | |||
| 615 | void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | ||
| 616 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); | ||
| 617 | |||
| 618 | int ipath_alloc_lkey(struct ipath_lkey_table *rkt, | ||
| 619 | struct ipath_mregion *mr); | ||
| 620 | |||
| 621 | void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey); | ||
| 622 | |||
| 623 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | ||
| 624 | struct ib_sge *sge, int acc); | ||
| 625 | |||
| 626 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | ||
| 627 | u32 len, u64 vaddr, u32 rkey, int acc); | ||
| 628 | |||
| 629 | int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | ||
| 630 | struct ib_recv_wr **bad_wr); | ||
| 631 | |||
| 632 | struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, | ||
| 633 | struct ib_srq_init_attr *srq_init_attr, | ||
| 634 | struct ib_udata *udata); | ||
| 635 | |||
| 636 | int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | ||
| 637 | enum ib_srq_attr_mask attr_mask); | ||
| 638 | |||
| 639 | int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); | ||
| 640 | |||
| 641 | int ipath_destroy_srq(struct ib_srq *ibsrq); | ||
| 642 | |||
| 643 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | ||
| 644 | |||
| 645 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); | ||
| 646 | |||
| 647 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, | ||
| 648 | struct ib_ucontext *context, | ||
| 649 | struct ib_udata *udata); | ||
| 650 | |||
| 651 | int ipath_destroy_cq(struct ib_cq *ibcq); | ||
| 652 | |||
| 653 | int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify); | ||
| 654 | |||
| 655 | int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata); | ||
| 656 | |||
| 657 | struct ib_mr *ipath_get_dma_mr(struct ib_pd *pd, int acc); | ||
| 658 | |||
| 659 | struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd, | ||
| 660 | struct ib_phys_buf *buffer_list, | ||
| 661 | int num_phys_buf, int acc, u64 *iova_start); | ||
| 662 | |||
| 663 | struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region, | ||
| 664 | int mr_access_flags, | ||
| 665 | struct ib_udata *udata); | ||
| 666 | |||
| 667 | int ipath_dereg_mr(struct ib_mr *ibmr); | ||
| 668 | |||
| 669 | struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags, | ||
| 670 | struct ib_fmr_attr *fmr_attr); | ||
| 671 | |||
| 672 | int ipath_map_phys_fmr(struct ib_fmr *ibfmr, u64 * page_list, | ||
| 673 | int list_len, u64 iova); | ||
| 674 | |||
| 675 | int ipath_unmap_fmr(struct list_head *fmr_list); | ||
| 676 | |||
| 677 | int ipath_dealloc_fmr(struct ib_fmr *ibfmr); | ||
| 678 | |||
| 679 | void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev); | ||
| 680 | |||
| 681 | void ipath_insert_rnr_queue(struct ipath_qp *qp); | ||
| 682 | |||
| 683 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); | ||
| 684 | |||
| 685 | void ipath_ruc_loopback(struct ipath_qp *sqp, struct ib_wc *wc); | ||
| 686 | |||
| 687 | extern const enum ib_wc_opcode ib_ipath_wc_opcode[]; | ||
| 688 | |||
| 689 | extern const u8 ipath_cvt_physportstate[]; | ||
| 690 | |||
| 691 | extern const int ib_ipath_state_ops[]; | ||
| 692 | |||
| 693 | extern unsigned int ib_ipath_lkey_table_size; | ||
| 694 | |||
| 695 | extern const u32 ib_ipath_rnr_table[]; | ||
| 696 | |||
| 697 | #endif /* IPATH_VERBS_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c new file mode 100644 index 000000000000..10b31d2c4f20 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c | |||
| @@ -0,0 +1,333 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <linux/list.h> | ||
| 34 | #include <linux/rcupdate.h> | ||
| 35 | |||
| 36 | #include "ipath_verbs.h" | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Global table of GID to attached QPs. | ||
| 40 | * The table is global to all ipath devices since a send from one QP/device | ||
| 41 | * needs to be locally routed to any locally attached QPs on the same | ||
| 42 | * or different device. | ||
| 43 | */ | ||
| 44 | static struct rb_root mcast_tree; | ||
| 45 | static DEFINE_SPINLOCK(mcast_lock); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * ipath_mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct | ||
| 49 | * @qp: the QP to link | ||
| 50 | */ | ||
| 51 | static struct ipath_mcast_qp *ipath_mcast_qp_alloc(struct ipath_qp *qp) | ||
| 52 | { | ||
| 53 | struct ipath_mcast_qp *mqp; | ||
| 54 | |||
| 55 | mqp = kmalloc(sizeof *mqp, GFP_KERNEL); | ||
| 56 | if (!mqp) | ||
| 57 | goto bail; | ||
| 58 | |||
| 59 | mqp->qp = qp; | ||
| 60 | atomic_inc(&qp->refcount); | ||
| 61 | |||
| 62 | bail: | ||
| 63 | return mqp; | ||
| 64 | } | ||
| 65 | |||
| 66 | static void ipath_mcast_qp_free(struct ipath_mcast_qp *mqp) | ||
| 67 | { | ||
| 68 | struct ipath_qp *qp = mqp->qp; | ||
| 69 | |||
| 70 | /* Notify ipath_destroy_qp() if it is waiting. */ | ||
| 71 | if (atomic_dec_and_test(&qp->refcount)) | ||
| 72 | wake_up(&qp->wait); | ||
| 73 | |||
| 74 | kfree(mqp); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * ipath_mcast_alloc - allocate the multicast GID structure | ||
| 79 | * @mgid: the multicast GID | ||
| 80 | * | ||
| 81 | * A list of QPs will be attached to this structure. | ||
| 82 | */ | ||
| 83 | static struct ipath_mcast *ipath_mcast_alloc(union ib_gid *mgid) | ||
| 84 | { | ||
| 85 | struct ipath_mcast *mcast; | ||
| 86 | |||
| 87 | mcast = kmalloc(sizeof *mcast, GFP_KERNEL); | ||
| 88 | if (!mcast) | ||
| 89 | goto bail; | ||
| 90 | |||
| 91 | mcast->mgid = *mgid; | ||
| 92 | INIT_LIST_HEAD(&mcast->qp_list); | ||
| 93 | init_waitqueue_head(&mcast->wait); | ||
| 94 | atomic_set(&mcast->refcount, 0); | ||
| 95 | |||
| 96 | bail: | ||
| 97 | return mcast; | ||
| 98 | } | ||
| 99 | |||
| 100 | static void ipath_mcast_free(struct ipath_mcast *mcast) | ||
| 101 | { | ||
| 102 | struct ipath_mcast_qp *p, *tmp; | ||
| 103 | |||
| 104 | list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) | ||
| 105 | ipath_mcast_qp_free(p); | ||
| 106 | |||
| 107 | kfree(mcast); | ||
| 108 | } | ||
| 109 | |||
| 110 | /** | ||
| 111 | * ipath_mcast_find - search the global table for the given multicast GID | ||
| 112 | * @mgid: the multicast GID to search for | ||
| 113 | * | ||
| 114 | * Returns NULL if not found. | ||
| 115 | * | ||
| 116 | * The caller is responsible for decrementing the reference count if found. | ||
| 117 | */ | ||
| 118 | struct ipath_mcast *ipath_mcast_find(union ib_gid *mgid) | ||
| 119 | { | ||
| 120 | struct rb_node *n; | ||
| 121 | unsigned long flags; | ||
| 122 | struct ipath_mcast *mcast; | ||
| 123 | |||
| 124 | spin_lock_irqsave(&mcast_lock, flags); | ||
| 125 | n = mcast_tree.rb_node; | ||
| 126 | while (n) { | ||
| 127 | int ret; | ||
| 128 | |||
| 129 | mcast = rb_entry(n, struct ipath_mcast, rb_node); | ||
| 130 | |||
| 131 | ret = memcmp(mgid->raw, mcast->mgid.raw, | ||
| 132 | sizeof(union ib_gid)); | ||
| 133 | if (ret < 0) | ||
| 134 | n = n->rb_left; | ||
| 135 | else if (ret > 0) | ||
| 136 | n = n->rb_right; | ||
| 137 | else { | ||
| 138 | atomic_inc(&mcast->refcount); | ||
| 139 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 140 | goto bail; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 144 | |||
| 145 | mcast = NULL; | ||
| 146 | |||
| 147 | bail: | ||
| 148 | return mcast; | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * ipath_mcast_add - insert mcast GID into table and attach QP struct | ||
| 153 | * @mcast: the mcast GID table | ||
| 154 | * @mqp: the QP to attach | ||
| 155 | * | ||
| 156 | * Return zero if both were added. Return EEXIST if the GID was already in | ||
| 157 | * the table but the QP was added. Return ESRCH if the QP was already | ||
| 158 | * attached and neither structure was added. | ||
| 159 | */ | ||
| 160 | static int ipath_mcast_add(struct ipath_mcast *mcast, | ||
| 161 | struct ipath_mcast_qp *mqp) | ||
| 162 | { | ||
| 163 | struct rb_node **n = &mcast_tree.rb_node; | ||
| 164 | struct rb_node *pn = NULL; | ||
| 165 | unsigned long flags; | ||
| 166 | int ret; | ||
| 167 | |||
| 168 | spin_lock_irqsave(&mcast_lock, flags); | ||
| 169 | |||
| 170 | while (*n) { | ||
| 171 | struct ipath_mcast *tmcast; | ||
| 172 | struct ipath_mcast_qp *p; | ||
| 173 | |||
| 174 | pn = *n; | ||
| 175 | tmcast = rb_entry(pn, struct ipath_mcast, rb_node); | ||
| 176 | |||
| 177 | ret = memcmp(mcast->mgid.raw, tmcast->mgid.raw, | ||
| 178 | sizeof(union ib_gid)); | ||
| 179 | if (ret < 0) { | ||
| 180 | n = &pn->rb_left; | ||
| 181 | continue; | ||
| 182 | } | ||
| 183 | if (ret > 0) { | ||
| 184 | n = &pn->rb_right; | ||
| 185 | continue; | ||
| 186 | } | ||
| 187 | |||
| 188 | /* Search the QP list to see if this is already there. */ | ||
| 189 | list_for_each_entry_rcu(p, &tmcast->qp_list, list) { | ||
| 190 | if (p->qp == mqp->qp) { | ||
| 191 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 192 | ret = ESRCH; | ||
| 193 | goto bail; | ||
| 194 | } | ||
| 195 | } | ||
| 196 | list_add_tail_rcu(&mqp->list, &tmcast->qp_list); | ||
| 197 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 198 | ret = EEXIST; | ||
| 199 | goto bail; | ||
| 200 | } | ||
| 201 | |||
| 202 | list_add_tail_rcu(&mqp->list, &mcast->qp_list); | ||
| 203 | |||
| 204 | atomic_inc(&mcast->refcount); | ||
| 205 | rb_link_node(&mcast->rb_node, pn, n); | ||
| 206 | rb_insert_color(&mcast->rb_node, &mcast_tree); | ||
| 207 | |||
| 208 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 209 | |||
| 210 | ret = 0; | ||
| 211 | |||
| 212 | bail: | ||
| 213 | return ret; | ||
| 214 | } | ||
| 215 | |||
| 216 | int ipath_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | ||
| 217 | { | ||
| 218 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 219 | struct ipath_mcast *mcast; | ||
| 220 | struct ipath_mcast_qp *mqp; | ||
| 221 | int ret; | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Allocate data structures since its better to do this outside of | ||
| 225 | * spin locks and it will most likely be needed. | ||
| 226 | */ | ||
| 227 | mcast = ipath_mcast_alloc(gid); | ||
| 228 | if (mcast == NULL) { | ||
| 229 | ret = -ENOMEM; | ||
| 230 | goto bail; | ||
| 231 | } | ||
| 232 | mqp = ipath_mcast_qp_alloc(qp); | ||
| 233 | if (mqp == NULL) { | ||
| 234 | ipath_mcast_free(mcast); | ||
| 235 | ret = -ENOMEM; | ||
| 236 | goto bail; | ||
| 237 | } | ||
| 238 | switch (ipath_mcast_add(mcast, mqp)) { | ||
| 239 | case ESRCH: | ||
| 240 | /* Neither was used: can't attach the same QP twice. */ | ||
| 241 | ipath_mcast_qp_free(mqp); | ||
| 242 | ipath_mcast_free(mcast); | ||
| 243 | ret = -EINVAL; | ||
| 244 | goto bail; | ||
| 245 | case EEXIST: /* The mcast wasn't used */ | ||
| 246 | ipath_mcast_free(mcast); | ||
| 247 | break; | ||
| 248 | default: | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | ret = 0; | ||
| 253 | |||
| 254 | bail: | ||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | |||
| 258 | int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | ||
| 259 | { | ||
| 260 | struct ipath_qp *qp = to_iqp(ibqp); | ||
| 261 | struct ipath_mcast *mcast = NULL; | ||
| 262 | struct ipath_mcast_qp *p, *tmp; | ||
| 263 | struct rb_node *n; | ||
| 264 | unsigned long flags; | ||
| 265 | int last = 0; | ||
| 266 | int ret; | ||
| 267 | |||
| 268 | spin_lock_irqsave(&mcast_lock, flags); | ||
| 269 | |||
| 270 | /* Find the GID in the mcast table. */ | ||
| 271 | n = mcast_tree.rb_node; | ||
| 272 | while (1) { | ||
| 273 | if (n == NULL) { | ||
| 274 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 275 | ret = 0; | ||
| 276 | goto bail; | ||
| 277 | } | ||
| 278 | |||
| 279 | mcast = rb_entry(n, struct ipath_mcast, rb_node); | ||
| 280 | ret = memcmp(gid->raw, mcast->mgid.raw, | ||
| 281 | sizeof(union ib_gid)); | ||
| 282 | if (ret < 0) | ||
| 283 | n = n->rb_left; | ||
| 284 | else if (ret > 0) | ||
| 285 | n = n->rb_right; | ||
| 286 | else | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | |||
| 290 | /* Search the QP list. */ | ||
| 291 | list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) { | ||
| 292 | if (p->qp != qp) | ||
| 293 | continue; | ||
| 294 | /* | ||
| 295 | * We found it, so remove it, but don't poison the forward | ||
| 296 | * link until we are sure there are no list walkers. | ||
| 297 | */ | ||
| 298 | list_del_rcu(&p->list); | ||
| 299 | |||
| 300 | /* If this was the last attached QP, remove the GID too. */ | ||
| 301 | if (list_empty(&mcast->qp_list)) { | ||
| 302 | rb_erase(&mcast->rb_node, &mcast_tree); | ||
| 303 | last = 1; | ||
| 304 | } | ||
| 305 | break; | ||
| 306 | } | ||
| 307 | |||
| 308 | spin_unlock_irqrestore(&mcast_lock, flags); | ||
| 309 | |||
| 310 | if (p) { | ||
| 311 | /* | ||
| 312 | * Wait for any list walkers to finish before freeing the | ||
| 313 | * list element. | ||
| 314 | */ | ||
| 315 | wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); | ||
| 316 | ipath_mcast_qp_free(p); | ||
| 317 | } | ||
| 318 | if (last) { | ||
| 319 | atomic_dec(&mcast->refcount); | ||
| 320 | wait_event(mcast->wait, !atomic_read(&mcast->refcount)); | ||
| 321 | ipath_mcast_free(mcast); | ||
| 322 | } | ||
| 323 | |||
| 324 | ret = 0; | ||
| 325 | |||
| 326 | bail: | ||
| 327 | return ret; | ||
| 328 | } | ||
| 329 | |||
| 330 | int ipath_mcast_tree_empty(void) | ||
| 331 | { | ||
| 332 | return mcast_tree.rb_node == NULL; | ||
| 333 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c new file mode 100644 index 000000000000..adc5322f15c1 --- /dev/null +++ b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* | ||
| 34 | * This file is conditionally built on x86_64 only. Otherwise weak symbol | ||
| 35 | * versions of the functions exported from here are used. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include <linux/pci.h> | ||
| 39 | #include <asm/mtrr.h> | ||
| 40 | #include <asm/processor.h> | ||
| 41 | |||
| 42 | #include "ipath_kernel.h" | ||
| 43 | |||
| 44 | /** | ||
| 45 | * ipath_enable_wc - enable write combining for MMIO writes to the device | ||
| 46 | * @dd: infinipath device | ||
| 47 | * | ||
| 48 | * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable | ||
| 49 | * write combining. | ||
| 50 | */ | ||
| 51 | int ipath_enable_wc(struct ipath_devdata *dd) | ||
| 52 | { | ||
| 53 | int ret = 0; | ||
| 54 | u64 pioaddr, piolen; | ||
| 55 | unsigned bits; | ||
| 56 | const unsigned long addr = pci_resource_start(dd->pcidev, 0); | ||
| 57 | const size_t len = pci_resource_len(dd->pcidev, 0); | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Set the PIO buffers to be WCCOMB, so we get HT bursts to the | ||
| 61 | * chip. Linux (possibly the hardware) requires it to be on a power | ||
| 62 | * of 2 address matching the length (which has to be a power of 2). | ||
| 63 | * For rev1, that means the base address, for rev2, it will be just | ||
| 64 | * the PIO buffers themselves. | ||
| 65 | */ | ||
| 66 | pioaddr = addr + dd->ipath_piobufbase; | ||
| 67 | piolen = (dd->ipath_piobcnt2k + | ||
| 68 | dd->ipath_piobcnt4k) * | ||
| 69 | ALIGN(dd->ipath_piobcnt2k + | ||
| 70 | dd->ipath_piobcnt4k, dd->ipath_palign); | ||
| 71 | |||
| 72 | for (bits = 0; !(piolen & (1ULL << bits)); bits++) | ||
| 73 | /* do nothing */ ; | ||
| 74 | |||
| 75 | if (piolen != (1ULL << bits)) { | ||
| 76 | piolen >>= bits; | ||
| 77 | while (piolen >>= 1) | ||
| 78 | bits++; | ||
| 79 | piolen = 1ULL << (bits + 1); | ||
| 80 | } | ||
| 81 | if (pioaddr & (piolen - 1)) { | ||
| 82 | u64 atmp; | ||
| 83 | ipath_dbg("pioaddr %llx not on right boundary for size " | ||
| 84 | "%llx, fixing\n", | ||
| 85 | (unsigned long long) pioaddr, | ||
| 86 | (unsigned long long) piolen); | ||
| 87 | atmp = pioaddr & ~(piolen - 1); | ||
| 88 | if (atmp < addr || (atmp + piolen) > (addr + len)) { | ||
| 89 | ipath_dev_err(dd, "No way to align address/size " | ||
| 90 | "(%llx/%llx), no WC mtrr\n", | ||
| 91 | (unsigned long long) atmp, | ||
| 92 | (unsigned long long) piolen << 1); | ||
| 93 | ret = -ENODEV; | ||
| 94 | } else { | ||
| 95 | ipath_dbg("changing WC base from %llx to %llx, " | ||
| 96 | "len from %llx to %llx\n", | ||
| 97 | (unsigned long long) pioaddr, | ||
| 98 | (unsigned long long) atmp, | ||
| 99 | (unsigned long long) piolen, | ||
| 100 | (unsigned long long) piolen << 1); | ||
| 101 | pioaddr = atmp; | ||
| 102 | piolen <<= 1; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | if (!ret) { | ||
| 107 | int cookie; | ||
| 108 | ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC " | ||
| 109 | "(addr %llx, len=0x%llx)\n", | ||
| 110 | (unsigned long long) pioaddr, | ||
| 111 | (unsigned long long) piolen); | ||
| 112 | cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); | ||
| 113 | if (cookie < 0) { | ||
| 114 | { | ||
| 115 | dev_info(&dd->pcidev->dev, | ||
| 116 | "mtrr_add() WC for PIO bufs " | ||
| 117 | "failed (%d)\n", | ||
| 118 | cookie); | ||
| 119 | ret = -EINVAL; | ||
| 120 | } | ||
| 121 | } else { | ||
| 122 | ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, " | ||
| 123 | "cookie is %d\n", cookie); | ||
| 124 | dd->ipath_wc_cookie = cookie; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | return ret; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * ipath_disable_wc - disable write combining for MMIO writes to the device | ||
| 133 | * @dd: infinipath device | ||
| 134 | */ | ||
| 135 | void ipath_disable_wc(struct ipath_devdata *dd) | ||
| 136 | { | ||
| 137 | if (dd->ipath_wc_cookie) { | ||
| 138 | ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n"); | ||
| 139 | mtrr_del(dd->ipath_wc_cookie, 0, 0); | ||
| 140 | dd->ipath_wc_cookie = 0; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * ipath_unordered_wc - indicate whether write combining is ordered | ||
| 146 | * | ||
| 147 | * Because our performance depends on our ability to do write combining mmio | ||
| 148 | * writes in the most efficient way, we need to know if we are on an Intel | ||
| 149 | * or AMD x86_64 processor. AMD x86_64 processors flush WC buffers out in | ||
| 150 | * the order completed, and so no special flushing is required to get | ||
| 151 | * correct ordering. Intel processors, however, will flush write buffers | ||
| 152 | * out in "random" orders, and so explicit ordering is needed at times. | ||
| 153 | */ | ||
| 154 | int ipath_unordered_wc(void) | ||
| 155 | { | ||
| 156 | return boot_cpu_data.x86_vendor != X86_VENDOR_AMD; | ||
| 157 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ips_common.h b/drivers/infiniband/hw/ipath/ips_common.h new file mode 100644 index 000000000000..410a764dfcef --- /dev/null +++ b/drivers/infiniband/hw/ipath/ips_common.h | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | #ifndef IPS_COMMON_H | ||
| 2 | #define IPS_COMMON_H | ||
| 3 | /* | ||
| 4 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * 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 | * General Public License (GPL) Version 2, available from the file | ||
| 9 | * COPYING in the main directory of this source tree, or the | ||
| 10 | * OpenIB.org BSD license below: | ||
| 11 | * | ||
| 12 | * Redistribution and use in source and binary forms, with or | ||
| 13 | * without modification, are permitted provided that the following | ||
| 14 | * conditions are met: | ||
| 15 | * | ||
| 16 | * - Redistributions of source code must retain the above | ||
| 17 | * copyright notice, this list of conditions and the following | ||
| 18 | * disclaimer. | ||
| 19 | * | ||
| 20 | * - Redistributions in binary form must reproduce the above | ||
| 21 | * copyright notice, this list of conditions and the following | ||
| 22 | * disclaimer in the documentation and/or other materials | ||
| 23 | * provided with the distribution. | ||
| 24 | * | ||
| 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 32 | * SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include "ipath_common.h" | ||
| 36 | |||
| 37 | struct ipath_header { | ||
| 38 | /* | ||
| 39 | * Version - 4 bits, Port - 4 bits, TID - 10 bits and Offset - | ||
| 40 | * 14 bits before ECO change ~28 Dec 03. After that, Vers 4, | ||
| 41 | * Port 3, TID 11, offset 14. | ||
| 42 | */ | ||
| 43 | __le32 ver_port_tid_offset; | ||
| 44 | __le16 chksum; | ||
| 45 | __le16 pkt_flags; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct ips_message_header { | ||
| 49 | __be16 lrh[4]; | ||
| 50 | __be32 bth[3]; | ||
| 51 | /* fields below this point are in host byte order */ | ||
| 52 | struct ipath_header iph; | ||
| 53 | __u8 sub_opcode; | ||
| 54 | __u8 flags; | ||
| 55 | __u16 src_rank; | ||
| 56 | /* 24 bits. The upper 8 bit is available for other use */ | ||
| 57 | union { | ||
| 58 | struct { | ||
| 59 | unsigned ack_seq_num:24; | ||
| 60 | unsigned port:4; | ||
| 61 | unsigned unused:4; | ||
| 62 | }; | ||
| 63 | __u32 ack_seq_num_org; | ||
| 64 | }; | ||
| 65 | __u8 expected_tid_session_id; | ||
| 66 | __u8 tinylen; /* to aid MPI */ | ||
| 67 | union { | ||
| 68 | __u16 tag; /* to aid MPI */ | ||
| 69 | __u16 mqhdr; /* for PSM MQ */ | ||
| 70 | }; | ||
| 71 | union { | ||
| 72 | __u32 mpi[4]; /* to aid MPI */ | ||
| 73 | __u32 data[4]; | ||
| 74 | __u64 mq[2]; /* for PSM MQ */ | ||
| 75 | struct { | ||
| 76 | __u16 mtu; | ||
| 77 | __u8 major_ver; | ||
| 78 | __u8 minor_ver; | ||
| 79 | __u32 not_used; //free | ||
| 80 | __u32 run_id; | ||
| 81 | __u32 client_ver; | ||
| 82 | }; | ||
| 83 | }; | ||
| 84 | }; | ||
| 85 | |||
| 86 | struct ether_header { | ||
| 87 | __be16 lrh[4]; | ||
| 88 | __be32 bth[3]; | ||
| 89 | struct ipath_header iph; | ||
| 90 | __u8 sub_opcode; | ||
| 91 | __u8 cmd; | ||
| 92 | __be16 lid; | ||
| 93 | __u16 mac[3]; | ||
| 94 | __u8 frag_num; | ||
| 95 | __u8 seq_num; | ||
| 96 | __le32 len; | ||
| 97 | /* MUST be of word size due to PIO write requirements */ | ||
| 98 | __u32 csum; | ||
| 99 | __le16 csum_offset; | ||
| 100 | __le16 flags; | ||
| 101 | __u16 first_2_bytes; | ||
| 102 | __u8 unused[2]; /* currently unused */ | ||
| 103 | }; | ||
| 104 | |||
| 105 | /* | ||
| 106 | * The PIO buffer used for sending infinipath messages must only be written | ||
| 107 | * in 32-bit words, all the data must be written, and no writes can occur | ||
| 108 | * after the last word is written (which transfers "ownership" of the buffer | ||
| 109 | * to the chip and triggers the message to be sent). | ||
| 110 | * Since the Linux sk_buff structure can be recursive, non-aligned, and | ||
| 111 | * any number of bytes in each segment, we use the following structure | ||
| 112 | * to keep information about the overall state of the copy operation. | ||
| 113 | * This is used to save the information needed to store the checksum | ||
| 114 | * in the right place before sending the last word to the hardware and | ||
| 115 | * to buffer the last 0-3 bytes of non-word sized segments. | ||
| 116 | */ | ||
| 117 | struct copy_data_s { | ||
| 118 | struct ether_header *hdr; | ||
| 119 | /* addr of PIO buf to write csum to */ | ||
| 120 | __u32 __iomem *csum_pio; | ||
| 121 | __u32 __iomem *to; /* addr of PIO buf to write data to */ | ||
| 122 | __u32 device; /* which device to allocate PIO bufs from */ | ||
| 123 | __s32 error; /* set if there is an error. */ | ||
| 124 | __s32 extra; /* amount of data saved in u.buf below */ | ||
| 125 | __u32 len; /* total length to send in bytes */ | ||
| 126 | __u32 flen; /* frament length in words */ | ||
| 127 | __u32 csum; /* partial IP checksum */ | ||
| 128 | __u32 pos; /* position for partial checksum */ | ||
| 129 | __u32 offset; /* offset to where data currently starts */ | ||
| 130 | __s32 checksum_calc; /* set to 1 when csum has been calculated */ | ||
| 131 | struct sk_buff *skb; | ||
| 132 | union { | ||
| 133 | __u32 w; | ||
| 134 | __u8 buf[4]; | ||
| 135 | } u; | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* IB - LRH header consts */ | ||
| 139 | #define IPS_LRH_GRH 0x0003 /* 1. word of IB LRH - next header: GRH */ | ||
| 140 | #define IPS_LRH_BTH 0x0002 /* 1. word of IB LRH - next header: BTH */ | ||
| 141 | |||
| 142 | #define IPS_OFFSET 0 | ||
| 143 | |||
| 144 | /* | ||
| 145 | * defines the cut-off point between the header queue and eager/expected | ||
| 146 | * TID queue | ||
| 147 | */ | ||
| 148 | #define NUM_OF_EXTRA_WORDS_IN_HEADER_QUEUE \ | ||
| 149 | ((sizeof(struct ips_message_header) - \ | ||
| 150 | offsetof(struct ips_message_header, iph)) >> 2) | ||
| 151 | |||
| 152 | /* OpCodes */ | ||
| 153 | #define OPCODE_IPS 0xC0 | ||
| 154 | #define OPCODE_ITH4X 0xC1 | ||
| 155 | |||
| 156 | /* OpCode 30 is use by stand-alone test programs */ | ||
| 157 | #define OPCODE_RAW_DATA 0xDE | ||
| 158 | /* last OpCode (31) is reserved for test */ | ||
| 159 | #define OPCODE_TEST 0xDF | ||
| 160 | |||
| 161 | /* sub OpCodes - ips */ | ||
| 162 | #define OPCODE_SEQ_DATA 0x01 | ||
| 163 | #define OPCODE_SEQ_CTRL 0x02 | ||
| 164 | |||
| 165 | #define OPCODE_SEQ_MQ_DATA 0x03 | ||
| 166 | #define OPCODE_SEQ_MQ_CTRL 0x04 | ||
| 167 | |||
| 168 | #define OPCODE_ACK 0x10 | ||
| 169 | #define OPCODE_NAK 0x11 | ||
| 170 | |||
| 171 | #define OPCODE_ERR_CHK 0x20 | ||
| 172 | #define OPCODE_ERR_CHK_PLS 0x21 | ||
| 173 | |||
| 174 | #define OPCODE_STARTUP 0x30 | ||
| 175 | #define OPCODE_STARTUP_ACK 0x31 | ||
| 176 | #define OPCODE_STARTUP_NAK 0x32 | ||
| 177 | |||
| 178 | #define OPCODE_STARTUP_EXT 0x34 | ||
| 179 | #define OPCODE_STARTUP_ACK_EXT 0x35 | ||
| 180 | #define OPCODE_STARTUP_NAK_EXT 0x36 | ||
| 181 | |||
| 182 | #define OPCODE_TIDS_RELEASE 0x40 | ||
| 183 | #define OPCODE_TIDS_RELEASE_CONFIRM 0x41 | ||
| 184 | |||
| 185 | #define OPCODE_CLOSE 0x50 | ||
| 186 | #define OPCODE_CLOSE_ACK 0x51 | ||
| 187 | /* | ||
| 188 | * like OPCODE_CLOSE, but no complaint if other side has already closed. | ||
| 189 | * Used when doing abort(), MPI_Abort(), etc. | ||
| 190 | */ | ||
| 191 | #define OPCODE_ABORT 0x52 | ||
| 192 | |||
| 193 | /* sub OpCodes - ith4x */ | ||
| 194 | #define OPCODE_ENCAP 0x81 | ||
| 195 | #define OPCODE_LID_ARP 0x82 | ||
| 196 | |||
| 197 | /* Receive Header Queue: receive type (from infinipath) */ | ||
| 198 | #define RCVHQ_RCV_TYPE_EXPECTED 0 | ||
| 199 | #define RCVHQ_RCV_TYPE_EAGER 1 | ||
| 200 | #define RCVHQ_RCV_TYPE_NON_KD 2 | ||
| 201 | #define RCVHQ_RCV_TYPE_ERROR 3 | ||
| 202 | |||
| 203 | /* misc. */ | ||
| 204 | #define SIZE_OF_CRC 1 | ||
| 205 | |||
| 206 | #define EAGER_TID_ID INFINIPATH_I_TID_MASK | ||
| 207 | |||
| 208 | #define IPS_DEFAULT_P_KEY 0xFFFF | ||
| 209 | |||
| 210 | #define IPS_PERMISSIVE_LID 0xFFFF | ||
| 211 | #define IPS_MULTICAST_LID_BASE 0xC000 | ||
| 212 | |||
| 213 | #define IPS_AETH_CREDIT_SHIFT 24 | ||
| 214 | #define IPS_AETH_CREDIT_MASK 0x1F | ||
| 215 | #define IPS_AETH_CREDIT_INVAL 0x1F | ||
| 216 | |||
| 217 | #define IPS_PSN_MASK 0xFFFFFF | ||
| 218 | #define IPS_MSN_MASK 0xFFFFFF | ||
| 219 | #define IPS_QPN_MASK 0xFFFFFF | ||
| 220 | #define IPS_MULTICAST_QPN 0xFFFFFF | ||
| 221 | |||
| 222 | /* functions for extracting fields from rcvhdrq entries */ | ||
| 223 | static inline __u32 ips_get_hdr_err_flags(const __le32 * rbuf) | ||
| 224 | { | ||
| 225 | return __le32_to_cpu(rbuf[1]); | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline __u32 ips_get_index(const __le32 * rbuf) | ||
| 229 | { | ||
| 230 | return (__le32_to_cpu(rbuf[0]) >> INFINIPATH_RHF_EGRINDEX_SHIFT) | ||
| 231 | & INFINIPATH_RHF_EGRINDEX_MASK; | ||
| 232 | } | ||
| 233 | |||
| 234 | static inline __u32 ips_get_rcv_type(const __le32 * rbuf) | ||
| 235 | { | ||
| 236 | return (__le32_to_cpu(rbuf[0]) >> INFINIPATH_RHF_RCVTYPE_SHIFT) | ||
| 237 | & INFINIPATH_RHF_RCVTYPE_MASK; | ||
| 238 | } | ||
| 239 | |||
| 240 | static inline __u32 ips_get_length_in_bytes(const __le32 * rbuf) | ||
| 241 | { | ||
| 242 | return ((__le32_to_cpu(rbuf[0]) >> INFINIPATH_RHF_LENGTH_SHIFT) | ||
| 243 | & INFINIPATH_RHF_LENGTH_MASK) << 2; | ||
| 244 | } | ||
| 245 | |||
| 246 | static inline void *ips_get_first_protocol_header(const __u32 * rbuf) | ||
| 247 | { | ||
| 248 | return (void *)&rbuf[2]; | ||
| 249 | } | ||
| 250 | |||
| 251 | static inline struct ips_message_header *ips_get_ips_header(const __u32 * | ||
| 252 | rbuf) | ||
| 253 | { | ||
| 254 | return (struct ips_message_header *)&rbuf[2]; | ||
| 255 | } | ||
| 256 | |||
| 257 | static inline __u32 ips_get_ipath_ver(__le32 hdrword) | ||
| 258 | { | ||
| 259 | return (__le32_to_cpu(hdrword) >> INFINIPATH_I_VERS_SHIFT) | ||
| 260 | & INFINIPATH_I_VERS_MASK; | ||
| 261 | } | ||
| 262 | |||
| 263 | #endif /* IPS_COMMON_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/verbs_debug.h b/drivers/infiniband/hw/ipath/verbs_debug.h new file mode 100644 index 000000000000..40d693cf3f94 --- /dev/null +++ b/drivers/infiniband/hw/ipath/verbs_debug.h | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This software is available to you under a choice of one of two | ||
| 5 | * licenses. You may choose to be licensed under the terms of the GNU | ||
| 6 | * General Public License (GPL) Version 2, available from the file | ||
| 7 | * COPYING in the main directory of this source tree, or the | ||
| 8 | * OpenIB.org BSD license below: | ||
| 9 | * | ||
| 10 | * Redistribution and use in source and binary forms, with or | ||
| 11 | * without modification, are permitted provided that the following | ||
| 12 | * conditions are met: | ||
| 13 | * | ||
| 14 | * - Redistributions of source code must retain the above | ||
| 15 | * copyright notice, this list of conditions and the following | ||
| 16 | * disclaimer. | ||
| 17 | * | ||
| 18 | * - Redistributions in binary form must reproduce the above | ||
| 19 | * copyright notice, this list of conditions and the following | ||
| 20 | * disclaimer in the documentation and/or other materials | ||
| 21 | * provided with the distribution. | ||
| 22 | * | ||
| 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
| 27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
| 28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 30 | * SOFTWARE. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _VERBS_DEBUG_H | ||
| 34 | #define _VERBS_DEBUG_H | ||
| 35 | |||
| 36 | /* | ||
| 37 | * This file contains tracing code for the ib_ipath kernel module. | ||
| 38 | */ | ||
| 39 | #ifndef _VERBS_DEBUGGING /* tracing enabled or not */ | ||
| 40 | #define _VERBS_DEBUGGING 1 | ||
| 41 | #endif | ||
| 42 | |||
| 43 | extern unsigned ib_ipath_debug; | ||
| 44 | |||
| 45 | #define _VERBS_ERROR(fmt,...) \ | ||
| 46 | do { \ | ||
| 47 | printk(KERN_ERR "%s: " fmt, "ib_ipath", ##__VA_ARGS__); \ | ||
| 48 | } while(0) | ||
| 49 | |||
| 50 | #define _VERBS_UNIT_ERROR(unit,fmt,...) \ | ||
| 51 | do { \ | ||
| 52 | printk(KERN_ERR "%s: " fmt, "ib_ipath", ##__VA_ARGS__); \ | ||
| 53 | } while(0) | ||
| 54 | |||
| 55 | #if _VERBS_DEBUGGING | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Mask values for debugging. The scheme allows us to compile out any | ||
| 59 | * of the debug tracing stuff, and if compiled in, to enable or | ||
| 60 | * disable dynamically. | ||
| 61 | * This can be set at modprobe time also: | ||
| 62 | * modprobe ib_path ib_ipath_debug=3 | ||
| 63 | */ | ||
| 64 | |||
| 65 | #define __VERBS_INFO 0x1 /* generic low verbosity stuff */ | ||
| 66 | #define __VERBS_DBG 0x2 /* generic debug */ | ||
| 67 | #define __VERBS_VDBG 0x4 /* verbose debug */ | ||
| 68 | #define __VERBS_SMADBG 0x8000 /* sma packet debug */ | ||
| 69 | |||
| 70 | #define _VERBS_INFO(fmt,...) \ | ||
| 71 | do { \ | ||
| 72 | if (unlikely(ib_ipath_debug&__VERBS_INFO)) \ | ||
| 73 | printk(KERN_INFO "%s: " fmt,"ib_ipath", \ | ||
| 74 | ##__VA_ARGS__); \ | ||
| 75 | } while(0) | ||
| 76 | |||
| 77 | #define _VERBS_DBG(fmt,...) \ | ||
| 78 | do { \ | ||
| 79 | if (unlikely(ib_ipath_debug&__VERBS_DBG)) \ | ||
| 80 | printk(KERN_DEBUG "%s: " fmt, __func__, \ | ||
| 81 | ##__VA_ARGS__); \ | ||
| 82 | } while(0) | ||
| 83 | |||
| 84 | #define _VERBS_VDBG(fmt,...) \ | ||
| 85 | do { \ | ||
| 86 | if (unlikely(ib_ipath_debug&__VERBS_VDBG)) \ | ||
| 87 | printk(KERN_DEBUG "%s: " fmt, __func__, \ | ||
| 88 | ##__VA_ARGS__); \ | ||
| 89 | } while(0) | ||
| 90 | |||
| 91 | #define _VERBS_SMADBG(fmt,...) \ | ||
| 92 | do { \ | ||
| 93 | if (unlikely(ib_ipath_debug&__VERBS_SMADBG)) \ | ||
| 94 | printk(KERN_DEBUG "%s: " fmt, __func__, \ | ||
| 95 | ##__VA_ARGS__); \ | ||
| 96 | } while(0) | ||
| 97 | |||
| 98 | #else /* ! _VERBS_DEBUGGING */ | ||
| 99 | |||
| 100 | #define _VERBS_INFO(fmt,...) | ||
| 101 | #define _VERBS_DBG(fmt,...) | ||
| 102 | #define _VERBS_VDBG(fmt,...) | ||
| 103 | #define _VERBS_SMADBG(fmt,...) | ||
| 104 | |||
| 105 | #endif /* _VERBS_DEBUGGING */ | ||
| 106 | |||
| 107 | #endif /* _VERBS_DEBUG_H */ | ||
