blob: 53b739df8cd5d13b514e52d3cc89be0b93ecf441 [file] [log] [blame]
Jon Masonfce8a7b2012-11-16 19:27:12 -07001/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2012 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * BSD LICENSE
14 *
15 * Copyright(c) 2012 Intel Corporation. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 *
21 * * Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * * Redistributions in binary form must reproduce the above copy
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * * Neither the name of Intel Corporation nor the names of its
28 * contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 * Intel PCIe NTB Linux driver
44 *
45 * Contact Information:
46 * Jon Mason <jon.mason@intel.com>
47 */
48#include <linux/debugfs.h>
Jon Mason113bf1c2012-11-16 18:52:57 -070049#include <linux/delay.h>
Jon Masonfce8a7b2012-11-16 19:27:12 -070050#include <linux/init.h>
51#include <linux/interrupt.h>
52#include <linux/module.h>
53#include <linux/pci.h>
Jon Mason113bf1c2012-11-16 18:52:57 -070054#include <linux/random.h>
Jon Masonfce8a7b2012-11-16 19:27:12 -070055#include <linux/slab.h>
56#include "ntb_hw.h"
57#include "ntb_regs.h"
58
59#define NTB_NAME "Intel(R) PCI-E Non-Transparent Bridge Driver"
Jon Masondb3bb3f2013-07-30 15:44:05 -070060#define NTB_VER "1.0"
Jon Masonfce8a7b2012-11-16 19:27:12 -070061
62MODULE_DESCRIPTION(NTB_NAME);
63MODULE_VERSION(NTB_VER);
64MODULE_LICENSE("Dual BSD/GPL");
65MODULE_AUTHOR("Intel Corporation");
66
67enum {
Jon Masoned6c24e2013-07-15 16:43:54 -070068 NTB_CONN_TRANSPARENT = 0,
Jon Masonfce8a7b2012-11-16 19:27:12 -070069 NTB_CONN_B2B,
70 NTB_CONN_RP,
71};
72
73enum {
74 NTB_DEV_USD = 0,
75 NTB_DEV_DSD,
76};
77
78enum {
79 SNB_HW = 0,
80 BWD_HW,
81};
82
Jon Mason1517a3f2013-07-30 15:58:49 -070083static struct dentry *debugfs_dir;
84
Jon Mason113bf1c2012-11-16 18:52:57 -070085#define BWD_LINK_RECOVERY_TIME 500
86
Jon Masonfce8a7b2012-11-16 19:27:12 -070087/* Translate memory window 0,1 to BAR 2,4 */
Jon Mason948d3a62013-04-18 17:07:36 -070088#define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2)
Jon Masonfce8a7b2012-11-16 19:27:12 -070089
Jon Mason53ca4fe2013-11-26 11:21:50 -070090static const struct pci_device_id ntb_pci_tbl[] = {
Jon Masonfce8a7b2012-11-16 19:27:12 -070091 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)},
92 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_JSF)},
Jon Masonfce8a7b2012-11-16 19:27:12 -070093 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SNB)},
Jon Masonbe4dac02012-09-28 11:38:48 -070094 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_IVT)},
95 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_HSX)},
96 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_JSF)},
97 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_SNB)},
98 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_IVT)},
99 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_PS_HSX)},
100 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_JSF)},
101 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_SNB)},
102 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_IVT)},
103 {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_SS_HSX)},
Jon Masonfce8a7b2012-11-16 19:27:12 -0700104 {0}
105};
106MODULE_DEVICE_TABLE(pci, ntb_pci_tbl);
107
Dave Jiangb775e852014-08-28 13:53:07 -0700108static int is_ntb_xeon(struct ntb_device *ndev)
109{
110 switch (ndev->pdev->device) {
111 case PCI_DEVICE_ID_INTEL_NTB_SS_JSF:
112 case PCI_DEVICE_ID_INTEL_NTB_SS_SNB:
113 case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
114 case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
115 case PCI_DEVICE_ID_INTEL_NTB_PS_JSF:
116 case PCI_DEVICE_ID_INTEL_NTB_PS_SNB:
117 case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
118 case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
119 case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF:
120 case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB:
121 case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
122 case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
123 return 1;
124 default:
125 return 0;
126 }
127
128 return 0;
129}
130
131static int is_ntb_atom(struct ntb_device *ndev)
132{
133 switch (ndev->pdev->device) {
134 case PCI_DEVICE_ID_INTEL_NTB_B2B_BWD:
135 return 1;
136 default:
137 return 0;
138 }
139
140 return 0;
141}
142
Dave Jiang069684e2014-08-28 13:53:18 -0700143static void ntb_set_errata_flags(struct ntb_device *ndev)
144{
145 switch (ndev->pdev->device) {
146 /*
147 * this workaround applies to all platform up to IvyBridge
148 * Haswell has splitbar support and use a different workaround
149 */
150 case PCI_DEVICE_ID_INTEL_NTB_SS_JSF:
151 case PCI_DEVICE_ID_INTEL_NTB_SS_SNB:
152 case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
153 case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
154 case PCI_DEVICE_ID_INTEL_NTB_PS_JSF:
155 case PCI_DEVICE_ID_INTEL_NTB_PS_SNB:
156 case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
157 case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
158 case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF:
159 case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB:
160 case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
161 case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
162 ndev->wa_flags |= WA_SNB_ERR;
163 break;
164 }
165}
166
Jon Masonfce8a7b2012-11-16 19:27:12 -0700167/**
168 * ntb_register_event_callback() - register event callback
169 * @ndev: pointer to ntb_device instance
170 * @func: callback function to register
171 *
172 * This function registers a callback for any HW driver events such as link
173 * up/down, power management notices and etc.
174 *
175 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
176 */
177int ntb_register_event_callback(struct ntb_device *ndev,
Jon Mason53ca4fe2013-11-26 11:21:50 -0700178 void (*func)(void *handle,
179 enum ntb_hw_event event))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700180{
181 if (ndev->event_cb)
182 return -EINVAL;
183
184 ndev->event_cb = func;
185
186 return 0;
187}
188
189/**
190 * ntb_unregister_event_callback() - unregisters the event callback
191 * @ndev: pointer to ntb_device instance
192 *
193 * This function unregisters the existing callback from transport
194 */
195void ntb_unregister_event_callback(struct ntb_device *ndev)
196{
197 ndev->event_cb = NULL;
198}
199
Jon Masone8aeb602013-04-18 17:59:44 -0700200static void ntb_irq_work(unsigned long data)
201{
202 struct ntb_db_cb *db_cb = (struct ntb_db_cb *)data;
203 int rc;
204
205 rc = db_cb->callback(db_cb->data, db_cb->db_num);
206 if (rc)
207 tasklet_schedule(&db_cb->irq_work);
208 else {
209 struct ntb_device *ndev = db_cb->ndev;
210 unsigned long mask;
211
212 mask = readw(ndev->reg_ofs.ldb_mask);
213 clear_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
214 writew(mask, ndev->reg_ofs.ldb_mask);
215 }
216}
217
Jon Masonfce8a7b2012-11-16 19:27:12 -0700218/**
219 * ntb_register_db_callback() - register a callback for doorbell interrupt
220 * @ndev: pointer to ntb_device instance
221 * @idx: doorbell index to register callback, zero based
Jon Masonf9a2cf82013-07-29 16:46:43 -0700222 * @data: pointer to be returned to caller with every callback
Jon Masonfce8a7b2012-11-16 19:27:12 -0700223 * @func: callback function to register
224 *
225 * This function registers a callback function for the doorbell interrupt
226 * on the primary side. The function will unmask the doorbell as well to
227 * allow interrupt.
228 *
229 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
230 */
231int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
Jon Masone8aeb602013-04-18 17:59:44 -0700232 void *data, int (*func)(void *data, int db_num))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700233{
234 unsigned long mask;
235
236 if (idx >= ndev->max_cbs || ndev->db_cb[idx].callback) {
237 dev_warn(&ndev->pdev->dev, "Invalid Index.\n");
238 return -EINVAL;
239 }
240
241 ndev->db_cb[idx].callback = func;
242 ndev->db_cb[idx].data = data;
Jon Masone8aeb602013-04-18 17:59:44 -0700243 ndev->db_cb[idx].ndev = ndev;
244
245 tasklet_init(&ndev->db_cb[idx].irq_work, ntb_irq_work,
246 (unsigned long) &ndev->db_cb[idx]);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700247
248 /* unmask interrupt */
Jon Mason49793882013-07-15 15:53:54 -0700249 mask = readw(ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700250 clear_bit(idx * ndev->bits_per_vector, &mask);
Jon Mason49793882013-07-15 15:53:54 -0700251 writew(mask, ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700252
253 return 0;
254}
255
256/**
257 * ntb_unregister_db_callback() - unregister a callback for doorbell interrupt
258 * @ndev: pointer to ntb_device instance
259 * @idx: doorbell index to register callback, zero based
260 *
261 * This function unregisters a callback function for the doorbell interrupt
262 * on the primary side. The function will also mask the said doorbell.
263 */
264void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx)
265{
266 unsigned long mask;
267
268 if (idx >= ndev->max_cbs || !ndev->db_cb[idx].callback)
269 return;
270
Jon Mason49793882013-07-15 15:53:54 -0700271 mask = readw(ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700272 set_bit(idx * ndev->bits_per_vector, &mask);
Jon Mason49793882013-07-15 15:53:54 -0700273 writew(mask, ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700274
Jon Masone8aeb602013-04-18 17:59:44 -0700275 tasklet_disable(&ndev->db_cb[idx].irq_work);
276
Jon Masonfce8a7b2012-11-16 19:27:12 -0700277 ndev->db_cb[idx].callback = NULL;
278}
279
280/**
281 * ntb_find_transport() - find the transport pointer
282 * @transport: pointer to pci device
283 *
284 * Given the pci device pointer, return the transport pointer passed in when
285 * the transport attached when it was inited.
286 *
287 * RETURNS: pointer to transport.
288 */
289void *ntb_find_transport(struct pci_dev *pdev)
290{
291 struct ntb_device *ndev = pci_get_drvdata(pdev);
292 return ndev->ntb_transport;
293}
294
295/**
296 * ntb_register_transport() - Register NTB transport with NTB HW driver
297 * @transport: transport identifier
298 *
299 * This function allows a transport to reserve the hardware driver for
300 * NTB usage.
301 *
302 * RETURNS: pointer to ntb_device, NULL on error.
303 */
304struct ntb_device *ntb_register_transport(struct pci_dev *pdev, void *transport)
305{
306 struct ntb_device *ndev = pci_get_drvdata(pdev);
307
308 if (ndev->ntb_transport)
309 return NULL;
310
311 ndev->ntb_transport = transport;
312 return ndev;
313}
314
315/**
316 * ntb_unregister_transport() - Unregister the transport with the NTB HW driver
317 * @ndev - ntb_device of the transport to be freed
318 *
319 * This function unregisters the transport from the HW driver and performs any
320 * necessary cleanups.
321 */
322void ntb_unregister_transport(struct ntb_device *ndev)
323{
324 int i;
325
326 if (!ndev->ntb_transport)
327 return;
328
329 for (i = 0; i < ndev->max_cbs; i++)
330 ntb_unregister_db_callback(ndev, i);
331
332 ntb_unregister_event_callback(ndev);
333 ndev->ntb_transport = NULL;
334}
335
336/**
Jon Masonfce8a7b2012-11-16 19:27:12 -0700337 * ntb_write_local_spad() - write to the secondary scratchpad register
338 * @ndev: pointer to ntb_device instance
339 * @idx: index to the scratchpad register, 0 based
340 * @val: the data value to put into the register
341 *
342 * This function allows writing of a 32bit value to the indexed scratchpad
343 * register. This writes over the data mirrored to the local scratchpad register
344 * by the remote system.
345 *
346 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
347 */
348int ntb_write_local_spad(struct ntb_device *ndev, unsigned int idx, u32 val)
349{
350 if (idx >= ndev->limits.max_spads)
351 return -EINVAL;
352
353 dev_dbg(&ndev->pdev->dev, "Writing %x to local scratch pad index %d\n",
354 val, idx);
355 writel(val, ndev->reg_ofs.spad_read + idx * 4);
356
357 return 0;
358}
359
360/**
361 * ntb_read_local_spad() - read from the primary scratchpad register
362 * @ndev: pointer to ntb_device instance
363 * @idx: index to scratchpad register, 0 based
364 * @val: pointer to 32bit integer for storing the register value
365 *
366 * This function allows reading of the 32bit scratchpad register on
367 * the primary (internal) side. This allows the local system to read data
368 * written and mirrored to the scratchpad register by the remote system.
369 *
370 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
371 */
372int ntb_read_local_spad(struct ntb_device *ndev, unsigned int idx, u32 *val)
373{
374 if (idx >= ndev->limits.max_spads)
375 return -EINVAL;
376
377 *val = readl(ndev->reg_ofs.spad_write + idx * 4);
378 dev_dbg(&ndev->pdev->dev,
379 "Reading %x from local scratch pad index %d\n", *val, idx);
380
381 return 0;
382}
383
384/**
385 * ntb_write_remote_spad() - write to the secondary scratchpad register
386 * @ndev: pointer to ntb_device instance
387 * @idx: index to the scratchpad register, 0 based
388 * @val: the data value to put into the register
389 *
390 * This function allows writing of a 32bit value to the indexed scratchpad
391 * register. The register resides on the secondary (external) side. This allows
392 * the local system to write data to be mirrored to the remote systems
393 * scratchpad register.
394 *
395 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
396 */
397int ntb_write_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 val)
398{
399 if (idx >= ndev->limits.max_spads)
400 return -EINVAL;
401
402 dev_dbg(&ndev->pdev->dev, "Writing %x to remote scratch pad index %d\n",
403 val, idx);
404 writel(val, ndev->reg_ofs.spad_write + idx * 4);
405
406 return 0;
407}
408
409/**
410 * ntb_read_remote_spad() - read from the primary scratchpad register
411 * @ndev: pointer to ntb_device instance
412 * @idx: index to scratchpad register, 0 based
413 * @val: pointer to 32bit integer for storing the register value
414 *
415 * This function allows reading of the 32bit scratchpad register on
416 * the primary (internal) side. This alloows the local system to read the data
417 * it wrote to be mirrored on the remote system.
418 *
419 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
420 */
421int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val)
422{
423 if (idx >= ndev->limits.max_spads)
424 return -EINVAL;
425
426 *val = readl(ndev->reg_ofs.spad_read + idx * 4);
427 dev_dbg(&ndev->pdev->dev,
428 "Reading %x from remote scratch pad index %d\n", *val, idx);
429
430 return 0;
431}
432
433/**
Jon Mason282a2fe2013-02-12 09:52:50 -0700434 * ntb_get_mw_base() - get addr for the NTB memory window
435 * @ndev: pointer to ntb_device instance
436 * @mw: memory window number
437 *
438 * This function provides the base address of the memory window specified.
439 *
440 * RETURNS: address, or NULL on error.
441 */
442resource_size_t ntb_get_mw_base(struct ntb_device *ndev, unsigned int mw)
443{
444 if (mw >= ntb_max_mw(ndev))
445 return 0;
446
447 return pci_resource_start(ndev->pdev, MW_TO_BAR(mw));
448}
449
450/**
Jon Masonfce8a7b2012-11-16 19:27:12 -0700451 * ntb_get_mw_vbase() - get virtual addr for the NTB memory window
452 * @ndev: pointer to ntb_device instance
453 * @mw: memory window number
454 *
455 * This function provides the base virtual address of the memory window
456 * specified.
457 *
458 * RETURNS: pointer to virtual address, or NULL on error.
459 */
Jon Mason74465642013-01-21 15:28:52 -0700460void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw)
Jon Masonfce8a7b2012-11-16 19:27:12 -0700461{
Jon Mason948d3a62013-04-18 17:07:36 -0700462 if (mw >= ntb_max_mw(ndev))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700463 return NULL;
464
465 return ndev->mw[mw].vbase;
466}
467
468/**
469 * ntb_get_mw_size() - return size of NTB memory window
470 * @ndev: pointer to ntb_device instance
471 * @mw: memory window number
472 *
473 * This function provides the physical size of the memory window specified
474 *
475 * RETURNS: the size of the memory window or zero on error
476 */
Jon Masonac477af2013-01-21 16:40:39 -0700477u64 ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw)
Jon Masonfce8a7b2012-11-16 19:27:12 -0700478{
Jon Mason948d3a62013-04-18 17:07:36 -0700479 if (mw >= ntb_max_mw(ndev))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700480 return 0;
481
482 return ndev->mw[mw].bar_sz;
483}
484
485/**
486 * ntb_set_mw_addr - set the memory window address
487 * @ndev: pointer to ntb_device instance
488 * @mw: memory window number
489 * @addr: base address for data
490 *
491 * This function sets the base physical address of the memory window. This
492 * memory address is where data from the remote system will be transfered into
493 * or out of depending on how the transport is configured.
494 */
495void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr)
496{
Jon Mason948d3a62013-04-18 17:07:36 -0700497 if (mw >= ntb_max_mw(ndev))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700498 return;
499
500 dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr,
501 MW_TO_BAR(mw));
502
503 ndev->mw[mw].phys_addr = addr;
504
505 switch (MW_TO_BAR(mw)) {
506 case NTB_BAR_23:
Jon Mason49793882013-07-15 15:53:54 -0700507 writeq(addr, ndev->reg_ofs.bar2_xlat);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700508 break;
509 case NTB_BAR_45:
Jon Mason49793882013-07-15 15:53:54 -0700510 writeq(addr, ndev->reg_ofs.bar4_xlat);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700511 break;
512 }
513}
514
515/**
Jon Mason49793882013-07-15 15:53:54 -0700516 * ntb_ring_doorbell() - Set the doorbell on the secondary/external side
Jon Masonfce8a7b2012-11-16 19:27:12 -0700517 * @ndev: pointer to ntb_device instance
518 * @db: doorbell to ring
519 *
520 * This function allows triggering of a doorbell on the secondary/external
521 * side that will initiate an interrupt on the remote host
522 *
523 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
524 */
Jon Mason49793882013-07-15 15:53:54 -0700525void ntb_ring_doorbell(struct ntb_device *ndev, unsigned int db)
Jon Masonfce8a7b2012-11-16 19:27:12 -0700526{
527 dev_dbg(&ndev->pdev->dev, "%s: ringing doorbell %d\n", __func__, db);
528
529 if (ndev->hw_type == BWD_HW)
Jon Mason49793882013-07-15 15:53:54 -0700530 writeq((u64) 1 << db, ndev->reg_ofs.rdb);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700531 else
532 writew(((1 << ndev->bits_per_vector) - 1) <<
Jon Mason49793882013-07-15 15:53:54 -0700533 (db * ndev->bits_per_vector), ndev->reg_ofs.rdb);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700534}
535
Jon Mason113bf1c2012-11-16 18:52:57 -0700536static void bwd_recover_link(struct ntb_device *ndev)
537{
538 u32 status;
539
540 /* Driver resets the NTB ModPhy lanes - magic! */
541 writeb(0xe0, ndev->reg_base + BWD_MODPHY_PCSREG6);
542 writeb(0x40, ndev->reg_base + BWD_MODPHY_PCSREG4);
543 writeb(0x60, ndev->reg_base + BWD_MODPHY_PCSREG4);
544 writeb(0x60, ndev->reg_base + BWD_MODPHY_PCSREG6);
545
546 /* Driver waits 100ms to allow the NTB ModPhy to settle */
547 msleep(100);
548
549 /* Clear AER Errors, write to clear */
550 status = readl(ndev->reg_base + BWD_ERRCORSTS_OFFSET);
551 dev_dbg(&ndev->pdev->dev, "ERRCORSTS = %x\n", status);
552 status &= PCI_ERR_COR_REP_ROLL;
553 writel(status, ndev->reg_base + BWD_ERRCORSTS_OFFSET);
554
555 /* Clear unexpected electrical idle event in LTSSM, write to clear */
556 status = readl(ndev->reg_base + BWD_LTSSMERRSTS0_OFFSET);
557 dev_dbg(&ndev->pdev->dev, "LTSSMERRSTS0 = %x\n", status);
558 status |= BWD_LTSSMERRSTS0_UNEXPECTEDEI;
559 writel(status, ndev->reg_base + BWD_LTSSMERRSTS0_OFFSET);
560
561 /* Clear DeSkew Buffer error, write to clear */
562 status = readl(ndev->reg_base + BWD_DESKEWSTS_OFFSET);
563 dev_dbg(&ndev->pdev->dev, "DESKEWSTS = %x\n", status);
564 status |= BWD_DESKEWSTS_DBERR;
565 writel(status, ndev->reg_base + BWD_DESKEWSTS_OFFSET);
566
567 status = readl(ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET);
568 dev_dbg(&ndev->pdev->dev, "IBSTERRRCRVSTS0 = %x\n", status);
569 status &= BWD_IBIST_ERR_OFLOW;
570 writel(status, ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET);
571
572 /* Releases the NTB state machine to allow the link to retrain */
573 status = readl(ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET);
574 dev_dbg(&ndev->pdev->dev, "LTSSMSTATEJMP = %x\n", status);
575 status &= ~BWD_LTSSMSTATEJMP_FORCEDETECT;
576 writel(status, ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET);
577}
578
Jon Masonfce8a7b2012-11-16 19:27:12 -0700579static void ntb_link_event(struct ntb_device *ndev, int link_state)
580{
581 unsigned int event;
582
583 if (ndev->link_status == link_state)
584 return;
585
586 if (link_state == NTB_LINK_UP) {
587 u16 status;
588
589 dev_info(&ndev->pdev->dev, "Link Up\n");
590 ndev->link_status = NTB_LINK_UP;
591 event = NTB_EVENT_HW_LINK_UP;
592
Dave Jiangb775e852014-08-28 13:53:07 -0700593 if (is_ntb_atom(ndev) ||
Jon Masoned6c24e2013-07-15 16:43:54 -0700594 ndev->conn_type == NTB_CONN_TRANSPARENT)
Jon Masonfce8a7b2012-11-16 19:27:12 -0700595 status = readw(ndev->reg_ofs.lnk_stat);
596 else {
597 int rc = pci_read_config_word(ndev->pdev,
598 SNB_LINK_STATUS_OFFSET,
599 &status);
600 if (rc)
601 return;
602 }
Jon Mason113bf1c2012-11-16 18:52:57 -0700603
604 ndev->link_width = (status & NTB_LINK_WIDTH_MASK) >> 4;
605 ndev->link_speed = (status & NTB_LINK_SPEED_MASK);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700606 dev_info(&ndev->pdev->dev, "Link Width %d, Link Speed %d\n",
Jon Mason113bf1c2012-11-16 18:52:57 -0700607 ndev->link_width, ndev->link_speed);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700608 } else {
609 dev_info(&ndev->pdev->dev, "Link Down\n");
610 ndev->link_status = NTB_LINK_DOWN;
611 event = NTB_EVENT_HW_LINK_DOWN;
Jon Mason113bf1c2012-11-16 18:52:57 -0700612 /* Don't modify link width/speed, we need it in link recovery */
Jon Masonfce8a7b2012-11-16 19:27:12 -0700613 }
614
615 /* notify the upper layer if we have an event change */
616 if (ndev->event_cb)
617 ndev->event_cb(ndev->ntb_transport, event);
618}
619
620static int ntb_link_status(struct ntb_device *ndev)
621{
622 int link_state;
623
Dave Jiangb775e852014-08-28 13:53:07 -0700624 if (is_ntb_atom(ndev)) {
Jon Masonfce8a7b2012-11-16 19:27:12 -0700625 u32 ntb_cntl;
626
627 ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
628 if (ntb_cntl & BWD_CNTL_LINK_DOWN)
629 link_state = NTB_LINK_DOWN;
630 else
631 link_state = NTB_LINK_UP;
632 } else {
633 u16 status;
634 int rc;
635
636 rc = pci_read_config_word(ndev->pdev, SNB_LINK_STATUS_OFFSET,
637 &status);
638 if (rc)
639 return rc;
640
641 if (status & NTB_LINK_STATUS_ACTIVE)
642 link_state = NTB_LINK_UP;
643 else
644 link_state = NTB_LINK_DOWN;
645 }
646
647 ntb_link_event(ndev, link_state);
648
649 return 0;
650}
651
Jon Mason113bf1c2012-11-16 18:52:57 -0700652static void bwd_link_recovery(struct work_struct *work)
653{
654 struct ntb_device *ndev = container_of(work, struct ntb_device,
655 lr_timer.work);
656 u32 status32;
657
658 bwd_recover_link(ndev);
659 /* There is a potential race between the 2 NTB devices recovering at the
660 * same time. If the times are the same, the link will not recover and
661 * the driver will be stuck in this loop forever. Add a random interval
662 * to the recovery time to prevent this race.
663 */
664 msleep(BWD_LINK_RECOVERY_TIME + prandom_u32() % BWD_LINK_RECOVERY_TIME);
665
666 status32 = readl(ndev->reg_base + BWD_LTSSMSTATEJMP_OFFSET);
667 if (status32 & BWD_LTSSMSTATEJMP_FORCEDETECT)
668 goto retry;
669
670 status32 = readl(ndev->reg_base + BWD_IBSTERRRCRVSTS0_OFFSET);
671 if (status32 & BWD_IBIST_ERR_OFLOW)
672 goto retry;
673
674 status32 = readl(ndev->reg_ofs.lnk_cntl);
675 if (!(status32 & BWD_CNTL_LINK_DOWN)) {
676 unsigned char speed, width;
677 u16 status16;
678
679 status16 = readw(ndev->reg_ofs.lnk_stat);
680 width = (status16 & NTB_LINK_WIDTH_MASK) >> 4;
681 speed = (status16 & NTB_LINK_SPEED_MASK);
682 if (ndev->link_width != width || ndev->link_speed != speed)
683 goto retry;
684 }
685
686 schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT);
687 return;
688
689retry:
690 schedule_delayed_work(&ndev->lr_timer, NTB_HB_TIMEOUT);
691}
692
Jon Masonfce8a7b2012-11-16 19:27:12 -0700693/* BWD doesn't have link status interrupt, poll on that platform */
694static void bwd_link_poll(struct work_struct *work)
695{
696 struct ntb_device *ndev = container_of(work, struct ntb_device,
697 hb_timer.work);
698 unsigned long ts = jiffies;
699
700 /* If we haven't gotten an interrupt in a while, check the BWD link
701 * status bit
702 */
703 if (ts > ndev->last_ts + NTB_HB_TIMEOUT) {
704 int rc = ntb_link_status(ndev);
705 if (rc)
706 dev_err(&ndev->pdev->dev,
707 "Error determining link status\n");
Jon Mason113bf1c2012-11-16 18:52:57 -0700708
709 /* Check to see if a link error is the cause of the link down */
710 if (ndev->link_status == NTB_LINK_DOWN) {
711 u32 status32 = readl(ndev->reg_base +
712 BWD_LTSSMSTATEJMP_OFFSET);
713 if (status32 & BWD_LTSSMSTATEJMP_FORCEDETECT) {
714 schedule_delayed_work(&ndev->lr_timer, 0);
715 return;
716 }
717 }
Jon Masonfce8a7b2012-11-16 19:27:12 -0700718 }
719
720 schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT);
721}
722
723static int ntb_xeon_setup(struct ntb_device *ndev)
724{
Dave Jiang1db97f22014-08-28 13:53:13 -0700725 switch (ndev->conn_type) {
Jon Masoned6c24e2013-07-15 16:43:54 -0700726 case NTB_CONN_B2B:
Jon Masoned6c24e2013-07-15 16:43:54 -0700727 ndev->reg_ofs.ldb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
728 ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET;
729 ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET;
730 ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET;
731 ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET;
732 ndev->limits.max_spads = SNB_MAX_B2B_SPADS;
733
734 /* There is a Xeon hardware errata related to writes to
735 * SDOORBELL or B2BDOORBELL in conjunction with inbound access
736 * to NTB MMIO Space, which may hang the system. To workaround
737 * this use the second memory window to access the interrupt and
738 * scratch pad registers on the remote system.
739 */
Dave Jiang069684e2014-08-28 13:53:18 -0700740 if (ndev->wa_flags & WA_SNB_ERR) {
Jon Masoned6c24e2013-07-15 16:43:54 -0700741 if (!ndev->mw[1].bar_sz)
742 return -EINVAL;
743
744 ndev->limits.max_mw = SNB_ERRATA_MAX_MW;
Jon Masonc529aa32013-09-06 16:51:16 -0700745 ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
Jon Masoned6c24e2013-07-15 16:43:54 -0700746 ndev->reg_ofs.spad_write = ndev->mw[1].vbase +
747 SNB_SPAD_OFFSET;
748 ndev->reg_ofs.rdb = ndev->mw[1].vbase +
749 SNB_PDOORBELL_OFFSET;
750
751 /* Set the Limit register to 4k, the minimum size, to
752 * prevent an illegal access
753 */
754 writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base +
755 SNB_PBAR4LMT_OFFSET);
Jon Mason58b88922013-11-01 15:08:19 -0700756 /* HW errata on the Limit registers. They can only be
757 * written when the base register is 4GB aligned and
Jon Mason53ca4fe2013-11-26 11:21:50 -0700758 * < 32bit. This should already be the case based on
759 * the driver defaults, but write the Limit registers
760 * first just in case.
Jon Mason58b88922013-11-01 15:08:19 -0700761 */
Jon Masoned6c24e2013-07-15 16:43:54 -0700762 } else {
763 ndev->limits.max_mw = SNB_MAX_MW;
Jon Masonc529aa32013-09-06 16:51:16 -0700764
765 /* HW Errata on bit 14 of b2bdoorbell register. Writes
766 * will not be mirrored to the remote system. Shrink
767 * the number of bits by one, since bit 14 is the last
768 * bit.
769 */
770 ndev->limits.max_db_bits = SNB_MAX_DB_BITS - 1;
Jon Masoned6c24e2013-07-15 16:43:54 -0700771 ndev->reg_ofs.spad_write = ndev->reg_base +
772 SNB_B2B_SPAD_OFFSET;
773 ndev->reg_ofs.rdb = ndev->reg_base +
774 SNB_B2B_DOORBELL_OFFSET;
775
776 /* Disable the Limit register, just incase it is set to
777 * something silly
778 */
779 writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET);
Jon Mason58b88922013-11-01 15:08:19 -0700780 /* HW errata on the Limit registers. They can only be
781 * written when the base register is 4GB aligned and
Jon Mason53ca4fe2013-11-26 11:21:50 -0700782 * < 32bit. This should already be the case based on
783 * the driver defaults, but write the Limit registers
784 * first just in case.
Jon Mason58b88922013-11-01 15:08:19 -0700785 */
Jon Masoned6c24e2013-07-15 16:43:54 -0700786 }
787
788 /* The Xeon errata workaround requires setting SBAR Base
789 * addresses to known values, so that the PBAR XLAT can be
790 * pointed at SBAR0 of the remote system.
791 */
792 if (ndev->dev_type == NTB_DEV_USD) {
793 writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base +
794 SNB_PBAR2XLAT_OFFSET);
Dave Jiang069684e2014-08-28 13:53:18 -0700795 if (ndev->wa_flags & WA_SNB_ERR)
Jon Masoned6c24e2013-07-15 16:43:54 -0700796 writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base +
797 SNB_PBAR4XLAT_OFFSET);
798 else {
799 writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base +
800 SNB_PBAR4XLAT_OFFSET);
801 /* B2B_XLAT_OFFSET is a 64bit register, but can
802 * only take 32bit writes
803 */
804 writel(SNB_MBAR01_DSD_ADDR & 0xffffffff,
805 ndev->reg_base + SNB_B2B_XLAT_OFFSETL);
806 writel(SNB_MBAR01_DSD_ADDR >> 32,
807 ndev->reg_base + SNB_B2B_XLAT_OFFSETU);
808 }
809
810 writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base +
811 SNB_SBAR0BASE_OFFSET);
812 writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base +
813 SNB_SBAR2BASE_OFFSET);
814 writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base +
815 SNB_SBAR4BASE_OFFSET);
816 } else {
817 writeq(SNB_MBAR23_USD_ADDR, ndev->reg_base +
818 SNB_PBAR2XLAT_OFFSET);
Dave Jiang069684e2014-08-28 13:53:18 -0700819 if (ndev->wa_flags & WA_SNB_ERR)
Jon Masoned6c24e2013-07-15 16:43:54 -0700820 writeq(SNB_MBAR01_USD_ADDR, ndev->reg_base +
821 SNB_PBAR4XLAT_OFFSET);
822 else {
823 writeq(SNB_MBAR45_USD_ADDR, ndev->reg_base +
824 SNB_PBAR4XLAT_OFFSET);
825 /* B2B_XLAT_OFFSET is a 64bit register, but can
826 * only take 32bit writes
827 */
Roland Dreierc8eee372014-02-21 08:07:21 -0800828 writel(SNB_MBAR01_USD_ADDR & 0xffffffff,
Jon Masoned6c24e2013-07-15 16:43:54 -0700829 ndev->reg_base + SNB_B2B_XLAT_OFFSETL);
830 writel(SNB_MBAR01_USD_ADDR >> 32,
831 ndev->reg_base + SNB_B2B_XLAT_OFFSETU);
832 }
833 writeq(SNB_MBAR01_DSD_ADDR, ndev->reg_base +
834 SNB_SBAR0BASE_OFFSET);
835 writeq(SNB_MBAR23_DSD_ADDR, ndev->reg_base +
836 SNB_SBAR2BASE_OFFSET);
837 writeq(SNB_MBAR45_DSD_ADDR, ndev->reg_base +
838 SNB_SBAR4BASE_OFFSET);
839 }
840 break;
841 case NTB_CONN_RP:
Dave Jiang069684e2014-08-28 13:53:18 -0700842 if (ndev->wa_flags & WA_SNB_ERR) {
Jon Mason53ca4fe2013-11-26 11:21:50 -0700843 dev_err(&ndev->pdev->dev,
Dave Jiang069684e2014-08-28 13:53:18 -0700844 "NTB-RP disabled due to hardware errata.\n");
Jon Masoned6c24e2013-07-15 16:43:54 -0700845 return -EINVAL;
846 }
847
848 /* Scratch pads need to have exclusive access from the primary
849 * or secondary side. Halve the num spads so that each side can
850 * have an equal amount.
851 */
852 ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
Jon Masonc529aa32013-09-06 16:51:16 -0700853 ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
Jon Masoned6c24e2013-07-15 16:43:54 -0700854 /* Note: The SDOORBELL is the cause of the errata. You REALLY
855 * don't want to touch it.
856 */
857 ndev->reg_ofs.rdb = ndev->reg_base + SNB_SDOORBELL_OFFSET;
858 ndev->reg_ofs.ldb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
859 ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_PDBMSK_OFFSET;
860 /* Offset the start of the spads to correspond to whether it is
861 * primary or secondary
862 */
863 ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET +
864 ndev->limits.max_spads * 4;
865 ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET;
866 ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_SBAR2XLAT_OFFSET;
867 ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_SBAR4XLAT_OFFSET;
868 ndev->limits.max_mw = SNB_MAX_MW;
869 break;
870 case NTB_CONN_TRANSPARENT:
Dave Jiang069684e2014-08-28 13:53:18 -0700871 if (ndev->wa_flags & WA_SNB_ERR) {
872 dev_err(&ndev->pdev->dev,
873 "NTB-TRANSPARENT disabled due to hardware errata.\n");
874 return -EINVAL;
875 }
876
Jon Masoned6c24e2013-07-15 16:43:54 -0700877 /* Scratch pads need to have exclusive access from the primary
878 * or secondary side. Halve the num spads so that each side can
879 * have an equal amount.
880 */
881 ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
Jon Masonc529aa32013-09-06 16:51:16 -0700882 ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
Jon Masoned6c24e2013-07-15 16:43:54 -0700883 ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
884 ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET;
885 ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET;
886 ndev->reg_ofs.spad_write = ndev->reg_base + SNB_SPAD_OFFSET;
887 /* Offset the start of the spads to correspond to whether it is
888 * primary or secondary
889 */
890 ndev->reg_ofs.spad_read = ndev->reg_base + SNB_SPAD_OFFSET +
891 ndev->limits.max_spads * 4;
892 ndev->reg_ofs.bar2_xlat = ndev->reg_base + SNB_PBAR2XLAT_OFFSET;
893 ndev->reg_ofs.bar4_xlat = ndev->reg_base + SNB_PBAR4XLAT_OFFSET;
894
895 ndev->limits.max_mw = SNB_MAX_MW;
896 break;
897 default:
Dave Jiang1db97f22014-08-28 13:53:13 -0700898 /*
899 * we should never hit this. the detect function should've
900 * take cared of everything.
Jon Masoned6c24e2013-07-15 16:43:54 -0700901 */
Jon Masoned6c24e2013-07-15 16:43:54 -0700902 return -EINVAL;
903 }
904
Jon Masonfce8a7b2012-11-16 19:27:12 -0700905 ndev->reg_ofs.lnk_cntl = ndev->reg_base + SNB_NTBCNTL_OFFSET;
Jon Masoned6c24e2013-07-15 16:43:54 -0700906 ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700907 ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET;
908
Jon Masonfce8a7b2012-11-16 19:27:12 -0700909 ndev->limits.msix_cnt = SNB_MSIX_CNT;
910 ndev->bits_per_vector = SNB_DB_BITS_PER_VEC;
911
912 return 0;
913}
914
915static int ntb_bwd_setup(struct ntb_device *ndev)
916{
917 int rc;
918 u32 val;
919
920 ndev->hw_type = BWD_HW;
921
922 rc = pci_read_config_dword(ndev->pdev, NTB_PPD_OFFSET, &val);
923 if (rc)
924 return rc;
925
926 switch ((val & BWD_PPD_CONN_TYPE) >> 8) {
927 case NTB_CONN_B2B:
928 ndev->conn_type = NTB_CONN_B2B;
929 break;
930 case NTB_CONN_RP:
931 default:
Jon Masonb1ef0042013-07-15 15:33:18 -0700932 dev_err(&ndev->pdev->dev, "Unsupported NTB configuration\n");
Jon Masonfce8a7b2012-11-16 19:27:12 -0700933 return -EINVAL;
934 }
935
936 if (val & BWD_PPD_DEV_TYPE)
937 ndev->dev_type = NTB_DEV_DSD;
938 else
939 ndev->dev_type = NTB_DEV_USD;
940
941 /* Initiate PCI-E link training */
942 rc = pci_write_config_dword(ndev->pdev, NTB_PPD_OFFSET,
943 val | BWD_PPD_INIT_LINK);
944 if (rc)
945 return rc;
946
Jon Mason49793882013-07-15 15:53:54 -0700947 ndev->reg_ofs.ldb = ndev->reg_base + BWD_PDOORBELL_OFFSET;
948 ndev->reg_ofs.ldb_mask = ndev->reg_base + BWD_PDBMSK_OFFSET;
Jon Masonb1ef0042013-07-15 15:33:18 -0700949 ndev->reg_ofs.rdb = ndev->reg_base + BWD_B2B_DOORBELL_OFFSET;
Jon Mason49793882013-07-15 15:53:54 -0700950 ndev->reg_ofs.bar2_xlat = ndev->reg_base + BWD_SBAR2XLAT_OFFSET;
951 ndev->reg_ofs.bar4_xlat = ndev->reg_base + BWD_SBAR4XLAT_OFFSET;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700952 ndev->reg_ofs.lnk_cntl = ndev->reg_base + BWD_NTBCNTL_OFFSET;
953 ndev->reg_ofs.lnk_stat = ndev->reg_base + BWD_LINK_STATUS_OFFSET;
954 ndev->reg_ofs.spad_read = ndev->reg_base + BWD_SPAD_OFFSET;
Jon Masonb1ef0042013-07-15 15:33:18 -0700955 ndev->reg_ofs.spad_write = ndev->reg_base + BWD_B2B_SPAD_OFFSET;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700956 ndev->reg_ofs.spci_cmd = ndev->reg_base + BWD_PCICMD_OFFSET;
Jon Mason948d3a62013-04-18 17:07:36 -0700957 ndev->limits.max_mw = BWD_MAX_MW;
Jon Masonb1ef0042013-07-15 15:33:18 -0700958 ndev->limits.max_spads = BWD_MAX_SPADS;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700959 ndev->limits.max_db_bits = BWD_MAX_DB_BITS;
960 ndev->limits.msix_cnt = BWD_MSIX_CNT;
961 ndev->bits_per_vector = BWD_DB_BITS_PER_VEC;
962
963 /* Since bwd doesn't have a link interrupt, setup a poll timer */
964 INIT_DELAYED_WORK(&ndev->hb_timer, bwd_link_poll);
Jon Mason113bf1c2012-11-16 18:52:57 -0700965 INIT_DELAYED_WORK(&ndev->lr_timer, bwd_link_recovery);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700966 schedule_delayed_work(&ndev->hb_timer, NTB_HB_TIMEOUT);
967
968 return 0;
969}
970
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -0800971static int ntb_device_setup(struct ntb_device *ndev)
Jon Masonfce8a7b2012-11-16 19:27:12 -0700972{
973 int rc;
974
Dave Jiangb775e852014-08-28 13:53:07 -0700975 if (is_ntb_xeon(ndev))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700976 rc = ntb_xeon_setup(ndev);
Dave Jiangb775e852014-08-28 13:53:07 -0700977 else if (is_ntb_atom(ndev))
Jon Masonfce8a7b2012-11-16 19:27:12 -0700978 rc = ntb_bwd_setup(ndev);
Dave Jiangb775e852014-08-28 13:53:07 -0700979 else
Jon Masonfce8a7b2012-11-16 19:27:12 -0700980 rc = -ENODEV;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700981
Jon Mason3b12a0d2013-07-15 13:23:47 -0700982 if (rc)
983 return rc;
984
Jon Masoned6c24e2013-07-15 16:43:54 -0700985 if (ndev->conn_type == NTB_CONN_B2B)
986 /* Enable Bus Master and Memory Space on the secondary side */
987 writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
988 ndev->reg_ofs.spci_cmd);
Jon Masonfce8a7b2012-11-16 19:27:12 -0700989
Jon Mason3b12a0d2013-07-15 13:23:47 -0700990 return 0;
Jon Masonfce8a7b2012-11-16 19:27:12 -0700991}
992
993static void ntb_device_free(struct ntb_device *ndev)
994{
Dave Jiangb775e852014-08-28 13:53:07 -0700995 if (is_ntb_atom(ndev)) {
Jon Masonfce8a7b2012-11-16 19:27:12 -0700996 cancel_delayed_work_sync(&ndev->hb_timer);
Jon Mason113bf1c2012-11-16 18:52:57 -0700997 cancel_delayed_work_sync(&ndev->lr_timer);
998 }
Jon Masonfce8a7b2012-11-16 19:27:12 -0700999}
1000
1001static irqreturn_t bwd_callback_msix_irq(int irq, void *data)
1002{
1003 struct ntb_db_cb *db_cb = data;
1004 struct ntb_device *ndev = db_cb->ndev;
Jon Masone8aeb602013-04-18 17:59:44 -07001005 unsigned long mask;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001006
1007 dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
1008 db_cb->db_num);
1009
Jon Masone8aeb602013-04-18 17:59:44 -07001010 mask = readw(ndev->reg_ofs.ldb_mask);
1011 set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
1012 writew(mask, ndev->reg_ofs.ldb_mask);
1013
1014 tasklet_schedule(&db_cb->irq_work);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001015
1016 /* No need to check for the specific HB irq, any interrupt means
1017 * we're connected.
1018 */
1019 ndev->last_ts = jiffies;
1020
Jon Mason49793882013-07-15 15:53:54 -07001021 writeq((u64) 1 << db_cb->db_num, ndev->reg_ofs.ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001022
1023 return IRQ_HANDLED;
1024}
1025
1026static irqreturn_t xeon_callback_msix_irq(int irq, void *data)
1027{
1028 struct ntb_db_cb *db_cb = data;
1029 struct ntb_device *ndev = db_cb->ndev;
Jon Masone8aeb602013-04-18 17:59:44 -07001030 unsigned long mask;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001031
1032 dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
1033 db_cb->db_num);
1034
Jon Masone8aeb602013-04-18 17:59:44 -07001035 mask = readw(ndev->reg_ofs.ldb_mask);
1036 set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
1037 writew(mask, ndev->reg_ofs.ldb_mask);
1038
1039 tasklet_schedule(&db_cb->irq_work);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001040
1041 /* On Sandybridge, there are 16 bits in the interrupt register
1042 * but only 4 vectors. So, 5 bits are assigned to the first 3
1043 * vectors, with the 4th having a single bit for link
1044 * interrupts.
1045 */
1046 writew(((1 << ndev->bits_per_vector) - 1) <<
Jon Mason49793882013-07-15 15:53:54 -07001047 (db_cb->db_num * ndev->bits_per_vector), ndev->reg_ofs.ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001048
1049 return IRQ_HANDLED;
1050}
1051
1052/* Since we do not have a HW doorbell in BWD, this is only used in JF/JT */
1053static irqreturn_t xeon_event_msix_irq(int irq, void *dev)
1054{
1055 struct ntb_device *ndev = dev;
1056 int rc;
1057
1058 dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for Events\n", irq);
1059
1060 rc = ntb_link_status(ndev);
1061 if (rc)
1062 dev_err(&ndev->pdev->dev, "Error determining link status\n");
1063
1064 /* bit 15 is always the link bit */
Jon Masonc529aa32013-09-06 16:51:16 -07001065 writew(1 << SNB_LINK_DB, ndev->reg_ofs.ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001066
1067 return IRQ_HANDLED;
1068}
1069
1070static irqreturn_t ntb_interrupt(int irq, void *dev)
1071{
1072 struct ntb_device *ndev = dev;
1073 unsigned int i = 0;
1074
Dave Jiangb775e852014-08-28 13:53:07 -07001075 if (is_ntb_atom(ndev)) {
Jon Mason49793882013-07-15 15:53:54 -07001076 u64 ldb = readq(ndev->reg_ofs.ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001077
Jon Mason49793882013-07-15 15:53:54 -07001078 dev_dbg(&ndev->pdev->dev, "irq %d - ldb = %Lx\n", irq, ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001079
Jon Mason49793882013-07-15 15:53:54 -07001080 while (ldb) {
1081 i = __ffs(ldb);
1082 ldb &= ldb - 1;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001083 bwd_callback_msix_irq(irq, &ndev->db_cb[i]);
1084 }
1085 } else {
Jon Mason49793882013-07-15 15:53:54 -07001086 u16 ldb = readw(ndev->reg_ofs.ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001087
Jon Mason49793882013-07-15 15:53:54 -07001088 dev_dbg(&ndev->pdev->dev, "irq %d - ldb = %x\n", irq, ldb);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001089
Jon Mason49793882013-07-15 15:53:54 -07001090 if (ldb & SNB_DB_HW_LINK) {
Jon Masonfce8a7b2012-11-16 19:27:12 -07001091 xeon_event_msix_irq(irq, dev);
Jon Mason49793882013-07-15 15:53:54 -07001092 ldb &= ~SNB_DB_HW_LINK;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001093 }
1094
Jon Mason49793882013-07-15 15:53:54 -07001095 while (ldb) {
1096 i = __ffs(ldb);
1097 ldb &= ldb - 1;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001098 xeon_callback_msix_irq(irq, &ndev->db_cb[i]);
1099 }
1100 }
1101
1102 return IRQ_HANDLED;
1103}
1104
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001105static int ntb_setup_snb_msix(struct ntb_device *ndev, int msix_entries)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001106{
1107 struct pci_dev *pdev = ndev->pdev;
1108 struct msix_entry *msix;
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001109 int rc, i;
1110
1111 if (msix_entries < ndev->limits.msix_cnt)
1112 return -ENOSPC;
1113
Alexander Gordeevf220baa2014-03-11 17:00:35 +01001114 rc = pci_enable_msix_exact(pdev, ndev->msix_entries, msix_entries);
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001115 if (rc < 0)
1116 return rc;
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001117
1118 for (i = 0; i < msix_entries; i++) {
1119 msix = &ndev->msix_entries[i];
1120 WARN_ON(!msix->vector);
1121
1122 if (i == msix_entries - 1) {
1123 rc = request_irq(msix->vector,
1124 xeon_event_msix_irq, 0,
1125 "ntb-event-msix", ndev);
1126 if (rc)
1127 goto err;
1128 } else {
1129 rc = request_irq(msix->vector,
1130 xeon_callback_msix_irq, 0,
1131 "ntb-callback-msix",
1132 &ndev->db_cb[i]);
1133 if (rc)
1134 goto err;
1135 }
1136 }
1137
1138 ndev->num_msix = msix_entries;
1139 ndev->max_cbs = msix_entries - 1;
1140
1141 return 0;
1142
1143err:
1144 while (--i >= 0) {
1145 /* Code never reaches here for entry nr 'ndev->num_msix - 1' */
1146 msix = &ndev->msix_entries[i];
1147 free_irq(msix->vector, &ndev->db_cb[i]);
1148 }
1149
1150 pci_disable_msix(pdev);
1151 ndev->num_msix = 0;
1152
1153 return rc;
1154}
1155
1156static int ntb_setup_bwd_msix(struct ntb_device *ndev, int msix_entries)
1157{
1158 struct pci_dev *pdev = ndev->pdev;
1159 struct msix_entry *msix;
1160 int rc, i;
1161
Alexander Gordeevf220baa2014-03-11 17:00:35 +01001162 msix_entries = pci_enable_msix_range(pdev, ndev->msix_entries,
1163 1, msix_entries);
1164 if (msix_entries < 0)
1165 return msix_entries;
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001166
1167 for (i = 0; i < msix_entries; i++) {
1168 msix = &ndev->msix_entries[i];
1169 WARN_ON(!msix->vector);
1170
1171 rc = request_irq(msix->vector, bwd_callback_msix_irq, 0,
1172 "ntb-callback-msix", &ndev->db_cb[i]);
1173 if (rc)
1174 goto err;
1175 }
1176
1177 ndev->num_msix = msix_entries;
1178 ndev->max_cbs = msix_entries;
1179
1180 return 0;
1181
1182err:
1183 while (--i >= 0)
1184 free_irq(msix->vector, &ndev->db_cb[i]);
1185
1186 pci_disable_msix(pdev);
1187 ndev->num_msix = 0;
1188
1189 return rc;
1190}
1191
1192static int ntb_setup_msix(struct ntb_device *ndev)
1193{
1194 struct pci_dev *pdev = ndev->pdev;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001195 int msix_entries;
Yijing Wang73f47ca2013-08-08 21:09:34 +08001196 int rc, i;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001197
Alexander Gordeev77733512014-02-21 16:49:30 +01001198 msix_entries = pci_msix_vec_count(pdev);
1199 if (msix_entries < 0) {
1200 rc = msix_entries;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001201 goto err;
Alexander Gordeev77733512014-02-21 16:49:30 +01001202 } else if (msix_entries > ndev->limits.msix_cnt) {
Jon Masonfce8a7b2012-11-16 19:27:12 -07001203 rc = -EINVAL;
1204 goto err;
1205 }
1206
1207 ndev->msix_entries = kmalloc(sizeof(struct msix_entry) * msix_entries,
1208 GFP_KERNEL);
1209 if (!ndev->msix_entries) {
1210 rc = -ENOMEM;
1211 goto err;
1212 }
1213
1214 for (i = 0; i < msix_entries; i++)
1215 ndev->msix_entries[i].entry = i;
1216
Dave Jiangb775e852014-08-28 13:53:07 -07001217 if (is_ntb_atom(ndev))
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001218 rc = ntb_setup_bwd_msix(ndev, msix_entries);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001219 else
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001220 rc = ntb_setup_snb_msix(ndev, msix_entries);
1221 if (rc)
1222 goto err1;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001223
1224 return 0;
1225
Jon Masonfce8a7b2012-11-16 19:27:12 -07001226err1:
1227 kfree(ndev->msix_entries);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001228err:
Alexander Gordeev53a788a2014-03-11 17:00:22 +01001229 dev_err(&pdev->dev, "Error allocating MSI-X interrupt\n");
Jon Masonfce8a7b2012-11-16 19:27:12 -07001230 return rc;
1231}
1232
1233static int ntb_setup_msi(struct ntb_device *ndev)
1234{
1235 struct pci_dev *pdev = ndev->pdev;
1236 int rc;
1237
1238 rc = pci_enable_msi(pdev);
1239 if (rc)
1240 return rc;
1241
1242 rc = request_irq(pdev->irq, ntb_interrupt, 0, "ntb-msi", ndev);
1243 if (rc) {
1244 pci_disable_msi(pdev);
1245 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
1246 return rc;
1247 }
1248
1249 return 0;
1250}
1251
1252static int ntb_setup_intx(struct ntb_device *ndev)
1253{
1254 struct pci_dev *pdev = ndev->pdev;
1255 int rc;
1256
1257 pci_msi_off(pdev);
1258
1259 /* Verify intx is enabled */
1260 pci_intx(pdev, 1);
1261
1262 rc = request_irq(pdev->irq, ntb_interrupt, IRQF_SHARED, "ntb-intx",
1263 ndev);
1264 if (rc)
1265 return rc;
1266
1267 return 0;
1268}
1269
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001270static int ntb_setup_interrupts(struct ntb_device *ndev)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001271{
1272 int rc;
1273
1274 /* On BWD, disable all interrupts. On SNB, disable all but Link
1275 * Interrupt. The rest will be unmasked as callbacks are registered.
1276 */
Dave Jiangb775e852014-08-28 13:53:07 -07001277 if (is_ntb_atom(ndev))
Jon Mason49793882013-07-15 15:53:54 -07001278 writeq(~0, ndev->reg_ofs.ldb_mask);
Jon Masonc529aa32013-09-06 16:51:16 -07001279 else {
1280 u16 var = 1 << SNB_LINK_DB;
1281 writew(~var, ndev->reg_ofs.ldb_mask);
1282 }
Jon Masonfce8a7b2012-11-16 19:27:12 -07001283
1284 rc = ntb_setup_msix(ndev);
1285 if (!rc)
1286 goto done;
1287
1288 ndev->bits_per_vector = 1;
1289 ndev->max_cbs = ndev->limits.max_db_bits;
1290
1291 rc = ntb_setup_msi(ndev);
1292 if (!rc)
1293 goto done;
1294
1295 rc = ntb_setup_intx(ndev);
1296 if (rc) {
1297 dev_err(&ndev->pdev->dev, "no usable interrupts\n");
1298 return rc;
1299 }
1300
1301done:
1302 return 0;
1303}
1304
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001305static void ntb_free_interrupts(struct ntb_device *ndev)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001306{
1307 struct pci_dev *pdev = ndev->pdev;
1308
1309 /* mask interrupts */
Dave Jiangb775e852014-08-28 13:53:07 -07001310 if (is_ntb_atom(ndev))
Jon Mason49793882013-07-15 15:53:54 -07001311 writeq(~0, ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001312 else
Jon Mason49793882013-07-15 15:53:54 -07001313 writew(~0, ndev->reg_ofs.ldb_mask);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001314
1315 if (ndev->num_msix) {
1316 struct msix_entry *msix;
1317 u32 i;
1318
1319 for (i = 0; i < ndev->num_msix; i++) {
1320 msix = &ndev->msix_entries[i];
Dave Jiangb775e852014-08-28 13:53:07 -07001321 if (is_ntb_xeon(ndev) && i == ndev->num_msix - 1)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001322 free_irq(msix->vector, ndev);
1323 else
1324 free_irq(msix->vector, &ndev->db_cb[i]);
1325 }
1326 pci_disable_msix(pdev);
Alexander Gordeev717e8e82014-02-21 16:49:29 +01001327 kfree(ndev->msix_entries);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001328 } else {
1329 free_irq(pdev->irq, ndev);
1330
1331 if (pci_dev_msi_enabled(pdev))
1332 pci_disable_msi(pdev);
1333 }
1334}
1335
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001336static int ntb_create_callbacks(struct ntb_device *ndev)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001337{
1338 int i;
1339
Jon Masonf9a2cf82013-07-29 16:46:43 -07001340 /* Chicken-egg issue. We won't know how many callbacks are necessary
Jon Masonfce8a7b2012-11-16 19:27:12 -07001341 * until we see how many MSI-X vectors we get, but these pointers need
Jon Masonf9a2cf82013-07-29 16:46:43 -07001342 * to be passed into the MSI-X register function. So, we allocate the
Jon Masonfce8a7b2012-11-16 19:27:12 -07001343 * max, knowing that they might not all be used, to work around this.
1344 */
1345 ndev->db_cb = kcalloc(ndev->limits.max_db_bits,
1346 sizeof(struct ntb_db_cb),
1347 GFP_KERNEL);
1348 if (!ndev->db_cb)
1349 return -ENOMEM;
1350
1351 for (i = 0; i < ndev->limits.max_db_bits; i++) {
1352 ndev->db_cb[i].db_num = i;
1353 ndev->db_cb[i].ndev = ndev;
1354 }
1355
1356 return 0;
1357}
1358
1359static void ntb_free_callbacks(struct ntb_device *ndev)
1360{
1361 int i;
1362
1363 for (i = 0; i < ndev->limits.max_db_bits; i++)
1364 ntb_unregister_db_callback(ndev, i);
1365
1366 kfree(ndev->db_cb);
1367}
1368
Jon Mason6465d022014-04-07 10:55:47 -07001369static ssize_t ntb_debugfs_read(struct file *filp, char __user *ubuf,
1370 size_t count, loff_t *offp)
1371{
1372 struct ntb_device *ndev;
1373 char *buf;
1374 ssize_t ret, offset, out_count;
1375
1376 out_count = 500;
1377
1378 buf = kmalloc(out_count, GFP_KERNEL);
1379 if (!buf)
1380 return -ENOMEM;
1381
1382 ndev = filp->private_data;
1383 offset = 0;
1384 offset += snprintf(buf + offset, out_count - offset,
1385 "NTB Device Information:\n");
1386 offset += snprintf(buf + offset, out_count - offset,
1387 "Connection Type - \t\t%s\n",
1388 ndev->conn_type == NTB_CONN_TRANSPARENT ?
1389 "Transparent" : (ndev->conn_type == NTB_CONN_B2B) ?
1390 "Back to back" : "Root Port");
1391 offset += snprintf(buf + offset, out_count - offset,
1392 "Device Type - \t\t\t%s\n",
1393 ndev->dev_type == NTB_DEV_USD ?
1394 "DSD/USP" : "USD/DSP");
1395 offset += snprintf(buf + offset, out_count - offset,
1396 "Max Number of Callbacks - \t%u\n",
1397 ntb_max_cbs(ndev));
1398 offset += snprintf(buf + offset, out_count - offset,
1399 "Link Status - \t\t\t%s\n",
1400 ntb_hw_link_status(ndev) ? "Up" : "Down");
1401 if (ntb_hw_link_status(ndev)) {
1402 offset += snprintf(buf + offset, out_count - offset,
1403 "Link Speed - \t\t\tPCI-E Gen %u\n",
1404 ndev->link_speed);
1405 offset += snprintf(buf + offset, out_count - offset,
1406 "Link Width - \t\t\tx%u\n",
1407 ndev->link_width);
1408 }
1409
Dave Jiangb775e852014-08-28 13:53:07 -07001410 if (is_ntb_xeon(ndev)) {
Jon Mason6465d022014-04-07 10:55:47 -07001411 u32 status32;
1412 u16 status16;
1413 int rc;
1414
1415 offset += snprintf(buf + offset, out_count - offset,
1416 "\nNTB Device Statistics:\n");
1417 offset += snprintf(buf + offset, out_count - offset,
1418 "Upstream Memory Miss - \t%u\n",
1419 readw(ndev->reg_base +
1420 SNB_USMEMMISS_OFFSET));
1421
1422 offset += snprintf(buf + offset, out_count - offset,
1423 "\nNTB Hardware Errors:\n");
1424
1425 rc = pci_read_config_word(ndev->pdev, SNB_DEVSTS_OFFSET,
1426 &status16);
1427 if (!rc)
1428 offset += snprintf(buf + offset, out_count - offset,
1429 "DEVSTS - \t%#06x\n", status16);
1430
1431 rc = pci_read_config_word(ndev->pdev, SNB_LINK_STATUS_OFFSET,
1432 &status16);
1433 if (!rc)
1434 offset += snprintf(buf + offset, out_count - offset,
1435 "LNKSTS - \t%#06x\n", status16);
1436
1437 rc = pci_read_config_dword(ndev->pdev, SNB_UNCERRSTS_OFFSET,
1438 &status32);
1439 if (!rc)
1440 offset += snprintf(buf + offset, out_count - offset,
1441 "UNCERRSTS - \t%#010x\n", status32);
1442
1443 rc = pci_read_config_dword(ndev->pdev, SNB_CORERRSTS_OFFSET,
1444 &status32);
1445 if (!rc)
1446 offset += snprintf(buf + offset, out_count - offset,
1447 "CORERRSTS - \t%#010x\n", status32);
1448 }
1449
1450 if (offset > out_count)
1451 offset = out_count;
1452
1453 ret = simple_read_from_buffer(ubuf, count, offp, buf, offset);
1454 kfree(buf);
1455 return ret;
1456}
1457
1458static const struct file_operations ntb_debugfs_info = {
1459 .owner = THIS_MODULE,
1460 .open = simple_open,
1461 .read = ntb_debugfs_read,
1462};
1463
Jon Mason1517a3f2013-07-30 15:58:49 -07001464static void ntb_setup_debugfs(struct ntb_device *ndev)
1465{
1466 if (!debugfs_initialized())
1467 return;
1468
1469 if (!debugfs_dir)
1470 debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
1471
1472 ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->pdev),
1473 debugfs_dir);
Jon Mason6465d022014-04-07 10:55:47 -07001474 if (ndev->debugfs_dir)
1475 ndev->debugfs_info = debugfs_create_file("info", S_IRUSR,
1476 ndev->debugfs_dir,
1477 ndev,
1478 &ntb_debugfs_info);
Jon Mason1517a3f2013-07-30 15:58:49 -07001479}
1480
1481static void ntb_free_debugfs(struct ntb_device *ndev)
1482{
1483 debugfs_remove_recursive(ndev->debugfs_dir);
1484
1485 if (debugfs_dir && simple_empty(debugfs_dir)) {
1486 debugfs_remove_recursive(debugfs_dir);
1487 debugfs_dir = NULL;
1488 }
1489}
1490
Jon Mason9fec60c2013-09-13 17:05:23 -07001491static void ntb_hw_link_up(struct ntb_device *ndev)
1492{
1493 if (ndev->conn_type == NTB_CONN_TRANSPARENT)
1494 ntb_link_event(ndev, NTB_LINK_UP);
Jon Mason78958432013-10-03 17:24:03 -07001495 else {
1496 u32 ntb_cntl;
1497
Jon Mason9fec60c2013-09-13 17:05:23 -07001498 /* Let's bring the NTB link up */
Jon Mason78958432013-10-03 17:24:03 -07001499 ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
1500 ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK);
1501 ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP;
1502 ntb_cntl |= NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP;
1503 writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
1504 }
Jon Mason9fec60c2013-09-13 17:05:23 -07001505}
1506
1507static void ntb_hw_link_down(struct ntb_device *ndev)
1508{
1509 u32 ntb_cntl;
1510
1511 if (ndev->conn_type == NTB_CONN_TRANSPARENT) {
1512 ntb_link_event(ndev, NTB_LINK_DOWN);
1513 return;
1514 }
1515
1516 /* Bring NTB link down */
1517 ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
Jon Mason78958432013-10-03 17:24:03 -07001518 ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP);
1519 ntb_cntl &= ~(NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP);
1520 ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK;
Jon Mason9fec60c2013-09-13 17:05:23 -07001521 writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
1522}
1523
Dave Jiang1db97f22014-08-28 13:53:13 -07001524static int ntb_xeon_detect(struct ntb_device *ndev)
1525{
1526 int rc;
1527 u8 ppd;
1528
1529 ndev->hw_type = SNB_HW;
1530
1531 rc = pci_read_config_byte(ndev->pdev, NTB_PPD_OFFSET, &ppd);
1532 if (rc)
1533 return -EIO;
1534
1535 if (ppd & SNB_PPD_DEV_TYPE)
1536 ndev->dev_type = NTB_DEV_USD;
1537 else
1538 ndev->dev_type = NTB_DEV_DSD;
1539
1540 switch (ppd & SNB_PPD_CONN_TYPE) {
1541 case NTB_CONN_B2B:
1542 dev_info(&ndev->pdev->dev, "Conn Type = B2B\n");
1543 ndev->conn_type = NTB_CONN_B2B;
1544 break;
1545 case NTB_CONN_RP:
1546 dev_info(&ndev->pdev->dev, "Conn Type = RP\n");
1547 ndev->conn_type = NTB_CONN_RP;
1548 break;
1549 case NTB_CONN_TRANSPARENT:
1550 dev_info(&ndev->pdev->dev, "Conn Type = TRANSPARENT\n");
1551 ndev->conn_type = NTB_CONN_TRANSPARENT;
1552 /*
1553 * This mode is default to USD/DSP. HW does not report
1554 * properly in transparent mode as it has no knowledge of
1555 * NTB. We will just force correct here.
1556 */
1557 ndev->dev_type = NTB_DEV_USD;
1558 break;
1559 default:
1560 dev_err(&ndev->pdev->dev, "Unknown PPD %x\n", ppd);
1561 return -ENODEV;
1562 }
1563
1564 return 0;
1565}
1566
1567static int ntb_atom_detect(struct ntb_device *ndev)
1568{
1569 int rc;
1570 u32 ppd;
1571
1572 ndev->hw_type = BWD_HW;
1573
1574 rc = pci_read_config_dword(ndev->pdev, NTB_PPD_OFFSET, &ppd);
1575 if (rc)
1576 return rc;
1577
1578 switch ((ppd & BWD_PPD_CONN_TYPE) >> 8) {
1579 case NTB_CONN_B2B:
1580 dev_info(&ndev->pdev->dev, "Conn Type = B2B\n");
1581 ndev->conn_type = NTB_CONN_B2B;
1582 break;
1583 case NTB_CONN_RP:
1584 default:
1585 dev_err(&ndev->pdev->dev, "Unsupported NTB configuration\n");
1586 return -EINVAL;
1587 }
1588
1589 if (ppd & BWD_PPD_DEV_TYPE)
1590 ndev->dev_type = NTB_DEV_DSD;
1591 else
1592 ndev->dev_type = NTB_DEV_USD;
1593
1594 return 0;
1595}
1596
1597static int ntb_device_detect(struct ntb_device *ndev)
1598{
1599 int rc;
1600
1601 if (is_ntb_xeon(ndev))
1602 rc = ntb_xeon_detect(ndev);
1603 else if (is_ntb_atom(ndev))
1604 rc = ntb_atom_detect(ndev);
1605 else
1606 rc = -ENODEV;
1607
1608 dev_info(&ndev->pdev->dev, "Device Type = %s\n",
1609 ndev->dev_type == NTB_DEV_USD ? "USD/DSP" : "DSD/USP");
1610
1611 return 0;
1612}
1613
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001614static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001615{
1616 struct ntb_device *ndev;
1617 int rc, i;
1618
1619 ndev = kzalloc(sizeof(struct ntb_device), GFP_KERNEL);
1620 if (!ndev)
1621 return -ENOMEM;
1622
1623 ndev->pdev = pdev;
Dave Jiang069684e2014-08-28 13:53:18 -07001624
1625 ntb_set_errata_flags(ndev);
1626
Jon Masonfce8a7b2012-11-16 19:27:12 -07001627 ndev->link_status = NTB_LINK_DOWN;
1628 pci_set_drvdata(pdev, ndev);
Jon Mason1517a3f2013-07-30 15:58:49 -07001629 ntb_setup_debugfs(ndev);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001630
1631 rc = pci_enable_device(pdev);
1632 if (rc)
1633 goto err;
1634
1635 pci_set_master(ndev->pdev);
1636
Dave Jiang1db97f22014-08-28 13:53:13 -07001637 rc = ntb_device_detect(ndev);
1638 if (rc)
1639 goto err;
1640
Jon Masonfce8a7b2012-11-16 19:27:12 -07001641 rc = pci_request_selected_regions(pdev, NTB_BAR_MASK, KBUILD_MODNAME);
1642 if (rc)
1643 goto err1;
1644
1645 ndev->reg_base = pci_ioremap_bar(pdev, NTB_BAR_MMIO);
1646 if (!ndev->reg_base) {
1647 dev_warn(&pdev->dev, "Cannot remap BAR 0\n");
1648 rc = -EIO;
1649 goto err2;
1650 }
1651
Jon Mason948d3a62013-04-18 17:07:36 -07001652 for (i = 0; i < NTB_MAX_NUM_MW; i++) {
Jon Masonfce8a7b2012-11-16 19:27:12 -07001653 ndev->mw[i].bar_sz = pci_resource_len(pdev, MW_TO_BAR(i));
1654 ndev->mw[i].vbase =
1655 ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)),
1656 ndev->mw[i].bar_sz);
Jon Mason113fc502013-01-30 11:40:52 -07001657 dev_info(&pdev->dev, "MW %d size %llu\n", i,
Jon Masonac477af2013-01-21 16:40:39 -07001658 (unsigned long long) ndev->mw[i].bar_sz);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001659 if (!ndev->mw[i].vbase) {
1660 dev_warn(&pdev->dev, "Cannot remap BAR %d\n",
1661 MW_TO_BAR(i));
1662 rc = -EIO;
1663 goto err3;
1664 }
1665 }
1666
1667 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
1668 if (rc) {
1669 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
1670 if (rc)
1671 goto err3;
1672
1673 dev_warn(&pdev->dev, "Cannot DMA highmem\n");
1674 }
1675
1676 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
1677 if (rc) {
1678 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
1679 if (rc)
1680 goto err3;
1681
1682 dev_warn(&pdev->dev, "Cannot DMA consistent highmem\n");
1683 }
1684
1685 rc = ntb_device_setup(ndev);
1686 if (rc)
1687 goto err3;
1688
1689 rc = ntb_create_callbacks(ndev);
1690 if (rc)
1691 goto err4;
1692
1693 rc = ntb_setup_interrupts(ndev);
1694 if (rc)
1695 goto err5;
1696
1697 /* The scratchpad registers keep the values between rmmod/insmod,
1698 * blast them now
1699 */
1700 for (i = 0; i < ndev->limits.max_spads; i++) {
1701 ntb_write_local_spad(ndev, i, 0);
1702 ntb_write_remote_spad(ndev, i, 0);
1703 }
1704
1705 rc = ntb_transport_init(pdev);
1706 if (rc)
1707 goto err6;
1708
Jon Mason9fec60c2013-09-13 17:05:23 -07001709 ntb_hw_link_up(ndev);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001710
1711 return 0;
1712
1713err6:
1714 ntb_free_interrupts(ndev);
1715err5:
1716 ntb_free_callbacks(ndev);
1717err4:
1718 ntb_device_free(ndev);
1719err3:
1720 for (i--; i >= 0; i--)
1721 iounmap(ndev->mw[i].vbase);
1722 iounmap(ndev->reg_base);
1723err2:
1724 pci_release_selected_regions(pdev, NTB_BAR_MASK);
1725err1:
1726 pci_disable_device(pdev);
1727err:
Jon Mason1517a3f2013-07-30 15:58:49 -07001728 ntb_free_debugfs(ndev);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001729 kfree(ndev);
1730
1731 dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME);
1732 return rc;
1733}
1734
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001735static void ntb_pci_remove(struct pci_dev *pdev)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001736{
1737 struct ntb_device *ndev = pci_get_drvdata(pdev);
1738 int i;
Jon Masonfce8a7b2012-11-16 19:27:12 -07001739
Jon Mason9fec60c2013-09-13 17:05:23 -07001740 ntb_hw_link_down(ndev);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001741
1742 ntb_transport_free(ndev->ntb_transport);
1743
1744 ntb_free_interrupts(ndev);
1745 ntb_free_callbacks(ndev);
1746 ntb_device_free(ndev);
1747
Jon Mason948d3a62013-04-18 17:07:36 -07001748 for (i = 0; i < NTB_MAX_NUM_MW; i++)
Jon Masonfce8a7b2012-11-16 19:27:12 -07001749 iounmap(ndev->mw[i].vbase);
1750
1751 iounmap(ndev->reg_base);
1752 pci_release_selected_regions(pdev, NTB_BAR_MASK);
1753 pci_disable_device(pdev);
Jon Mason1517a3f2013-07-30 15:58:49 -07001754 ntb_free_debugfs(ndev);
Jon Masonfce8a7b2012-11-16 19:27:12 -07001755 kfree(ndev);
1756}
1757
1758static struct pci_driver ntb_pci_driver = {
1759 .name = KBUILD_MODNAME,
1760 .id_table = ntb_pci_tbl,
1761 .probe = ntb_pci_probe,
Greg Kroah-Hartman78a61ab2013-01-17 19:17:42 -08001762 .remove = ntb_pci_remove,
Jon Masonfce8a7b2012-11-16 19:27:12 -07001763};
Jon Mason6465d022014-04-07 10:55:47 -07001764
Jon Masonfce8a7b2012-11-16 19:27:12 -07001765module_pci_driver(ntb_pci_driver);