Commit 04578e84 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ntb-4.20' of git://github.com/jonmason/ntb

Pull NTB updates from Jon Mason:
 "Fairly minor changes and bug fixes:

  NTB IDT thermal changes and hook into hwmon, ntb_netdev clean-up of
  private struct, and a few bug fixes"

* tag 'ntb-4.20' of git://github.com/jonmason/ntb:
  ntb: idt: Alter the driver info comments
  ntb: idt: Discard temperature sensor IRQ handler
  ntb: idt: Add basic hwmon sysfs interface
  ntb: idt: Alter temperature read method
  ntb_netdev: Simplify remove with client device drvdata
  NTB: transport: Try harder to alloc an aligned MW buffer
  ntb: ntb_transport: Mark expected switch fall-throughs
  ntb: idt: Set PCIe bus address to BARLIMITx
  NTB: ntb_hw_idt: replace IS_ERR_OR_NULL with regular NULL checks
  ntb: intel: fix return value for ndev_vec_mask()
  ntb_netdev: fix sleep time mismatch
parents 71e56028 a662315d
......@@ -71,7 +71,6 @@ static unsigned int tx_start = 10;
static unsigned int tx_stop = 5;
struct ntb_netdev {
struct list_head list;
struct pci_dev *pdev;
struct net_device *ndev;
struct ntb_transport_qp *qp;
......@@ -81,8 +80,6 @@ struct ntb_netdev {
#define NTB_TX_TIMEOUT_MS 1000
#define NTB_RXQ_SIZE 100
static LIST_HEAD(dev_list);
static void ntb_netdev_event_handler(void *data, int link_is_up)
{
struct net_device *ndev = data;
......@@ -236,7 +233,7 @@ static void ntb_netdev_tx_timer(struct timer_list *t)
struct net_device *ndev = dev->ndev;
if (ntb_transport_tx_free_entry(dev->qp) < tx_stop) {
mod_timer(&dev->tx_timer, jiffies + msecs_to_jiffies(tx_time));
mod_timer(&dev->tx_timer, jiffies + usecs_to_jiffies(tx_time));
} else {
/* Make sure anybody stopping the queue after this sees the new
* value of ntb_transport_tx_free_entry()
......@@ -452,7 +449,7 @@ static int ntb_netdev_probe(struct device *client_dev)
if (rc)
goto err1;
list_add(&dev->list, &dev_list);
dev_set_drvdata(client_dev, ndev);
dev_info(&pdev->dev, "%s created\n", ndev->name);
return 0;
......@@ -465,27 +462,8 @@ static int ntb_netdev_probe(struct device *client_dev)
static void ntb_netdev_remove(struct device *client_dev)
{
struct ntb_dev *ntb;
struct net_device *ndev;
struct pci_dev *pdev;
struct ntb_netdev *dev;
bool found = false;
ntb = dev_ntb(client_dev->parent);
pdev = ntb->pdev;
list_for_each_entry(dev, &dev_list, list) {
if (dev->pdev == pdev) {
found = true;
break;
}
}
if (!found)
return;
list_del(&dev->list);
ndev = dev->ndev;
struct net_device *ndev = dev_get_drvdata(client_dev);
struct ntb_netdev *dev = netdev_priv(ndev);
unregister_netdev(ndev);
ntb_transport_free_queue(dev->qp);
......
config NTB_IDT
tristate "IDT PCIe-switch Non-Transparent Bridge support"
depends on PCI
select HWMON
help
This driver supports NTB of cappable IDT PCIe-switches.
......@@ -23,9 +24,7 @@ config NTB_IDT
BAR settings of peer NT-functions, the BAR setups can't be done over
kernel PCI fixups. That's why the alternative pre-initialization
techniques like BIOS using SMBus interface or EEPROM should be
utilized. Additionally if one needs to have temperature sensor
information printed to system log, the corresponding registers must
be initialized within BIOS/EEPROM as well.
utilized.
If unsure, say N.
This diff is collapsed.
......@@ -4,7 +4,7 @@
*
* GPL LICENSE SUMMARY
*
* Copyright (C) 2016 T-Platforms All Rights Reserved.
* Copyright (C) 2016-2018 T-Platforms JSC All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
......@@ -47,9 +47,9 @@
#include <linux/pci_ids.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/ntb.h>
/*
* Macro is used to create the struct pci_device_id that matches
* the supported IDT PCIe-switches
......@@ -688,15 +688,14 @@
* @IDT_NTINTMSK_DBELL: Doorbell interrupt mask bit
* @IDT_NTINTMSK_SEVENT: Switch Event interrupt mask bit
* @IDT_NTINTMSK_TMPSENSOR: Temperature sensor interrupt mask bit
* @IDT_NTINTMSK_ALL: All the useful interrupts mask
* @IDT_NTINTMSK_ALL: NTB-related interrupts mask
*/
#define IDT_NTINTMSK_MSG 0x00000001U
#define IDT_NTINTMSK_DBELL 0x00000002U
#define IDT_NTINTMSK_SEVENT 0x00000008U
#define IDT_NTINTMSK_TMPSENSOR 0x00000080U
#define IDT_NTINTMSK_ALL \
(IDT_NTINTMSK_MSG | IDT_NTINTMSK_DBELL | \
IDT_NTINTMSK_SEVENT | IDT_NTINTMSK_TMPSENSOR)
(IDT_NTINTMSK_MSG | IDT_NTINTMSK_DBELL | IDT_NTINTMSK_SEVENT)
/*
* NTGSIGNAL register fields related constants
......@@ -885,13 +884,61 @@
#define IDT_SWPxMSGCTL_PART_MASK 0x00000070U
#define IDT_SWPxMSGCTL_PART_FLD 4
/*
* TMPCTL register fields related constants
* @IDT_TMPCTL_LTH_MASK: Low temperature threshold field mask
* @IDT_TMPCTL_LTH_FLD: Low temperature threshold field offset
* @IDT_TMPCTL_MTH_MASK: Middle temperature threshold field mask
* @IDT_TMPCTL_MTH_FLD: Middle temperature threshold field offset
* @IDT_TMPCTL_HTH_MASK: High temperature threshold field mask
* @IDT_TMPCTL_HTH_FLD: High temperature threshold field offset
* @IDT_TMPCTL_PDOWN: Temperature sensor power down
*/
#define IDT_TMPCTL_LTH_MASK 0x000000FFU
#define IDT_TMPCTL_LTH_FLD 0
#define IDT_TMPCTL_MTH_MASK 0x0000FF00U
#define IDT_TMPCTL_MTH_FLD 8
#define IDT_TMPCTL_HTH_MASK 0x00FF0000U
#define IDT_TMPCTL_HTH_FLD 16
#define IDT_TMPCTL_PDOWN 0x80000000U
/*
* TMPSTS register fields related constants
* @IDT_TMPSTS_TEMP_MASK: Current temperature field mask
* @IDT_TMPSTS_TEMP_FLD: Current temperature field offset
* @IDT_TMPSTS_LTEMP_MASK: Lowest temperature field mask
* @IDT_TMPSTS_LTEMP_FLD: Lowest temperature field offset
* @IDT_TMPSTS_HTEMP_MASK: Highest temperature field mask
* @IDT_TMPSTS_HTEMP_FLD: Highest temperature field offset
*/
#define IDT_TMPSTS_TEMP_MASK 0x000000FFU
#define IDT_TMPSTS_TEMP_FLD 0
#define IDT_TMPSTS_LTEMP_MASK 0x0000FF00U
#define IDT_TMPSTS_LTEMP_FLD 8
#define IDT_TMPSTS_HTEMP_MASK 0x00FF0000U
#define IDT_TMPSTS_HTEMP_FLD 16
/*
* TMPALARM register fields related constants
* @IDT_TMPALARM_LTEMP_MASK: Lowest temperature field mask
* @IDT_TMPALARM_LTEMP_FLD: Lowest temperature field offset
* @IDT_TMPALARM_HTEMP_MASK: Highest temperature field mask
* @IDT_TMPALARM_HTEMP_FLD: Highest temperature field offset
* @IDT_TMPALARM_IRQ_MASK: Alarm IRQ status mask
*/
#define IDT_TMPALARM_LTEMP_MASK 0x0000FF00U
#define IDT_TMPALARM_LTEMP_FLD 8
#define IDT_TMPALARM_HTEMP_MASK 0x00FF0000U
#define IDT_TMPALARM_HTEMP_FLD 16
#define IDT_TMPALARM_IRQ_MASK 0x3F000000U
/*
* TMPADJ register fields related constants
* @IDT_TMPADJ_OFFSET_MASK: Temperature value offset field mask
* @IDT_TMPADJ_OFFSET_FLD: Temperature value offset field offset
*/
#define IDT_TMPADJ_OFFSET_MASK 0x000000FFU
#define IDT_TMPADJ_OFFSET_FLD 0
/*
* Helper macro to get/set the corresponding field value
......@@ -950,6 +997,32 @@
#define IDT_TRANS_ALIGN 4
#define IDT_DIR_SIZE_ALIGN 1
/*
* IDT PCIe-switch temperature sensor value limits
* @IDT_TEMP_MIN_MDEG: Minimal integer value of temperature
* @IDT_TEMP_MAX_MDEG: Maximal integer value of temperature
* @IDT_TEMP_MIN_OFFSET:Minimal integer value of temperature offset
* @IDT_TEMP_MAX_OFFSET:Maximal integer value of temperature offset
*/
#define IDT_TEMP_MIN_MDEG 0
#define IDT_TEMP_MAX_MDEG 127500
#define IDT_TEMP_MIN_OFFSET -64000
#define IDT_TEMP_MAX_OFFSET 63500
/*
* Temperature sensor values enumeration
* @IDT_TEMP_CUR: Current temperature
* @IDT_TEMP_LOW: Lowest historical temperature
* @IDT_TEMP_HIGH: Highest historical temperature
* @IDT_TEMP_OFFSET: Current temperature offset
*/
enum idt_temp_val {
IDT_TEMP_CUR,
IDT_TEMP_LOW,
IDT_TEMP_HIGH,
IDT_TEMP_OFFSET
};
/*
* IDT Memory Windows type. Depending on the device settings, IDT supports
* Direct Address Translation MW registers and Lookup Table registers
......@@ -1044,6 +1117,8 @@ struct idt_ntb_peer {
* @msg_mask_lock: Message mask register lock
* @gasa_lock: GASA registers access lock
*
* @hwmon_mtx: Temperature sensor interface update mutex
*
* @dbgfs_info: DebugFS info node
*/
struct idt_ntb_dev {
......@@ -1071,6 +1146,8 @@ struct idt_ntb_dev {
spinlock_t msg_mask_lock;
spinlock_t gasa_lock;
struct mutex hwmon_mtx;
struct dentry *dbgfs_info;
};
#define to_ndev_ntb(__ntb) container_of(__ntb, struct idt_ntb_dev, ntb)
......
......@@ -265,7 +265,7 @@ static inline int ndev_db_clear_mask(struct intel_ntb_dev *ndev, u64 db_bits,
return 0;
}
static inline int ndev_vec_mask(struct intel_ntb_dev *ndev, int db_vector)
static inline u64 ndev_vec_mask(struct intel_ntb_dev *ndev, int db_vector)
{
u64 shift, mask;
......
......@@ -194,6 +194,8 @@ struct ntb_transport_mw {
void __iomem *vbase;
size_t xlat_size;
size_t buff_size;
size_t alloc_size;
void *alloc_addr;
void *virt_addr;
dma_addr_t dma_addr;
};
......@@ -672,13 +674,59 @@ static void ntb_free_mw(struct ntb_transport_ctx *nt, int num_mw)
return;
ntb_mw_clear_trans(nt->ndev, PIDX, num_mw);
dma_free_coherent(&pdev->dev, mw->buff_size,
mw->virt_addr, mw->dma_addr);
dma_free_coherent(&pdev->dev, mw->alloc_size,
mw->alloc_addr, mw->dma_addr);
mw->xlat_size = 0;
mw->buff_size = 0;
mw->alloc_size = 0;
mw->alloc_addr = NULL;
mw->virt_addr = NULL;
}
static int ntb_alloc_mw_buffer(struct ntb_transport_mw *mw,
struct device *dma_dev, size_t align)
{
dma_addr_t dma_addr;
void *alloc_addr, *virt_addr;
int rc;
alloc_addr = dma_alloc_coherent(dma_dev, mw->alloc_size,
&dma_addr, GFP_KERNEL);
if (!alloc_addr) {
dev_err(dma_dev, "Unable to alloc MW buff of size %zu\n",
mw->alloc_size);
return -ENOMEM;
}
virt_addr = alloc_addr;
/*
* we must ensure that the memory address allocated is BAR size
* aligned in order for the XLAT register to take the value. This
* is a requirement of the hardware. It is recommended to setup CMA
* for BAR sizes equal or greater than 4MB.
*/
if (!IS_ALIGNED(dma_addr, align)) {
if (mw->alloc_size > mw->buff_size) {
virt_addr = PTR_ALIGN(alloc_addr, align);
dma_addr = ALIGN(dma_addr, align);
} else {
rc = -ENOMEM;
goto err;
}
}
mw->alloc_addr = alloc_addr;
mw->virt_addr = virt_addr;
mw->dma_addr = dma_addr;
return 0;
err:
dma_free_coherent(dma_dev, mw->alloc_size, alloc_addr, dma_addr);
return rc;
}
static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
resource_size_t size)
{
......@@ -710,28 +758,20 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
/* Alloc memory for receiving data. Must be aligned */
mw->xlat_size = xlat_size;
mw->buff_size = buff_size;
mw->alloc_size = buff_size;
mw->virt_addr = dma_alloc_coherent(&pdev->dev, buff_size,
&mw->dma_addr, GFP_KERNEL);
if (!mw->virt_addr) {
mw->xlat_size = 0;
mw->buff_size = 0;
dev_err(&pdev->dev, "Unable to alloc MW buff of size %zu\n",
buff_size);
return -ENOMEM;
}
/*
* we must ensure that the memory address allocated is BAR size
* aligned in order for the XLAT register to take the value. This
* is a requirement of the hardware. It is recommended to setup CMA
* for BAR sizes equal or greater than 4MB.
*/
if (!IS_ALIGNED(mw->dma_addr, xlat_align)) {
dev_err(&pdev->dev, "DMA memory %pad is not aligned\n",
&mw->dma_addr);
ntb_free_mw(nt, num_mw);
return -ENOMEM;
rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align);
if (rc) {
mw->alloc_size *= 2;
rc = ntb_alloc_mw_buffer(mw, &pdev->dev, xlat_align);
if (rc) {
dev_err(&pdev->dev,
"Unable to alloc aligned MW buff\n");
mw->xlat_size = 0;
mw->buff_size = 0;
mw->alloc_size = 0;
return rc;
}
}
/* Notify HW the memory location of the receive buffer */
......@@ -1278,6 +1318,7 @@ static void ntb_rx_copy_callback(void *data,
case DMA_TRANS_READ_FAILED:
case DMA_TRANS_WRITE_FAILED:
entry->errors++;
/* fall through */
case DMA_TRANS_ABORTED:
{
struct ntb_transport_qp *qp = entry->qp;
......@@ -1533,6 +1574,7 @@ static void ntb_tx_copy_callback(void *data,
case DMA_TRANS_READ_FAILED:
case DMA_TRANS_WRITE_FAILED:
entry->errors++;
/* fall through */
case DMA_TRANS_ABORTED:
{
void __iomem *offset =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment