mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
InfiniBand/RDMA changes for the 3.5 merge window:
- Add ocrdma hardware driver for Emulex IB-over-Ethernet adapters
- Add generic and mlx4 support for "raw" QPs: allow suitably privileged
applications to send and receive arbitrary packets directly to/from
the hardware
- Add "doorbell drop" handling to the cxgb4 driver
- A fairly large batch of qib hardware driver changes
- A few fixes for lockdep-detected issues
- A few other miscellaneous fixes and cleanups
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
iQIcBAABCAAGBQJPumbZAAoJEENa44ZhAt0h8LgP/0fXe7Szm3n6P6UvMAVqkagM
4PpreH3mpWUFpzqeQE1JPDtgx700R6aPipbHqgIN+k61RWMpLjICGcNx7iwxn1I+
zqdquGygWgjceLz+BLVlk+iBmJt3vZ3fPRAXc7fdP+jhIarWkNIOy1pXWTUuRvED
jL8jIaxhCcgAVzm/zNyt6IPxkaHvCz7K9wqmpyU0dsO9OyPdGvWA9+CkGXwmOCPq
mxSVhWnfGsMkPBsL7EgTC5KP/ox2PKq6rFgysmVVS+rKCpP0L8BEVQyGX3Gf8KA8
yV+KdTi9ofDnFrv6R7Wz0v7HRUih8GRssakzBu7Y7HLfK1M/QwMG0GUAibXGZObc
vUXuQ3uRJ/cIzMPXqKeGYwpb5t+TmxyjhWu44OjCUQkNau91+9BSbA69S88KXc49
aTJiCZlhPuGf4uGMWJJuPLcE2xO2QCZj+8ckL2STYrIip6GWlCH02kJaQmRkuWH2
UhMOeJDBC4nvh4EQT/WwHpGzyhkavE2ayfo5YemxBJXo+P5Mdbf7WIDRQDLUEeQH
F8sPoccH4hDiAorN/SkTsm14jVTP7oWW1M40Ont59Nhbgm88MsVkvjoneHnfBvbD
HjK92soCWnYTAoREfj0G4xUxZgMdOZcezWrX0rx5LJ8Ju9y4zAi3cKGr7lg6hs4X
syKfN0VjiDRtJ+pxayi3
=yWfr
-----END PGP SIGNATURE-----
Merge tag 'rdma-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull InfiniBand/RDMA changes from Roland Dreier:
- Add ocrdma hardware driver for Emulex IB-over-Ethernet adapters
- Add generic and mlx4 support for "raw" QPs: allow suitably privileged
applications to send and receive arbitrary packets directly to/from
the hardware
- Add "doorbell drop" handling to the cxgb4 driver
- A fairly large batch of qib hardware driver changes
- A few fixes for lockdep-detected issues
- A few other miscellaneous fixes and cleanups
Fix up trivial conflict in drivers/net/ethernet/emulex/benet/be.h.
* tag 'rdma-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (53 commits)
RDMA/cxgb4: Include vmalloc.h for vmalloc and vfree
IB/mlx4: Fix mlx4_ib_add() error flow
IB/core: Fix IB_SA_COMP_MASK macro
IB/iser: Fix error flow in iser ep connection establishment
IB/mlx4: Increase the number of vectors (EQs) available for ULPs
RDMA/cxgb4: Add query_qp support
RDMA/cxgb4: Remove kfifo usage
RDMA/cxgb4: Use vmalloc() for debugfs QP dump
RDMA/cxgb4: DB Drop Recovery for RDMA and LLD queues
RDMA/cxgb4: Disable interrupts in c4iw_ev_dispatch()
RDMA/cxgb4: Add DB Overflow Avoidance
RDMA/cxgb4: Add debugfs RDMA memory stats
cxgb4: DB Drop Recovery for RDMA and LLD queues
cxgb4: Common platform specific changes for DB Drop Recovery
cxgb4: Detect DB FULL events and notify RDMA ULD
RDMA/cxgb4: Drop peer_abort when no endpoint found
RDMA/cxgb4: Always wake up waiters in c4iw_peer_abort_intr()
mlx4_core: Change bitmap allocator to work in round-robin fashion
RDMA/nes: Don't call event handler if pointer is NULL
RDMA/nes: Fix for the ORD value of the connecting peer
...
This commit is contained in:
commit
c23ddf7857
80 changed files with 10546 additions and 447 deletions
|
|
@ -51,6 +51,8 @@
|
|||
#define FW_VERSION_MINOR 1
|
||||
#define FW_VERSION_MICRO 0
|
||||
|
||||
#define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
|
||||
|
||||
enum {
|
||||
MAX_NPORTS = 4, /* max # of ports */
|
||||
SERNUM_LEN = 24, /* Serial # length */
|
||||
|
|
@ -64,6 +66,15 @@ enum {
|
|||
MEM_MC
|
||||
};
|
||||
|
||||
enum {
|
||||
MEMWIN0_APERTURE = 65536,
|
||||
MEMWIN0_BASE = 0x30000,
|
||||
MEMWIN1_APERTURE = 32768,
|
||||
MEMWIN1_BASE = 0x28000,
|
||||
MEMWIN2_APERTURE = 2048,
|
||||
MEMWIN2_BASE = 0x1b800,
|
||||
};
|
||||
|
||||
enum dev_master {
|
||||
MASTER_CANT,
|
||||
MASTER_MAY,
|
||||
|
|
@ -403,6 +414,9 @@ struct sge_txq {
|
|||
struct tx_sw_desc *sdesc; /* address of SW Tx descriptor ring */
|
||||
struct sge_qstat *stat; /* queue status entry */
|
||||
dma_addr_t phys_addr; /* physical address of the ring */
|
||||
spinlock_t db_lock;
|
||||
int db_disabled;
|
||||
unsigned short db_pidx;
|
||||
};
|
||||
|
||||
struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */
|
||||
|
|
@ -475,6 +489,7 @@ struct adapter {
|
|||
void __iomem *regs;
|
||||
struct pci_dev *pdev;
|
||||
struct device *pdev_dev;
|
||||
unsigned int mbox;
|
||||
unsigned int fn;
|
||||
unsigned int flags;
|
||||
|
||||
|
|
@ -504,6 +519,8 @@ struct adapter {
|
|||
void **tid_release_head;
|
||||
spinlock_t tid_release_lock;
|
||||
struct work_struct tid_release_task;
|
||||
struct work_struct db_full_task;
|
||||
struct work_struct db_drop_task;
|
||||
bool tid_release_task_busy;
|
||||
|
||||
struct dentry *debugfs_root;
|
||||
|
|
@ -605,6 +622,7 @@ irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
|
|||
void t4_sge_init(struct adapter *adap);
|
||||
void t4_sge_start(struct adapter *adap);
|
||||
void t4_sge_stop(struct adapter *adap);
|
||||
extern int dbfifo_int_thresh;
|
||||
|
||||
#define for_each_port(adapter, iter) \
|
||||
for (iter = 0; iter < (adapter)->params.nports; ++iter)
|
||||
|
|
@ -719,4 +737,9 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
|
|||
int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
|
||||
unsigned int vf, unsigned int eqid);
|
||||
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
|
||||
void t4_db_full(struct adapter *adapter);
|
||||
void t4_db_dropped(struct adapter *adapter);
|
||||
int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len);
|
||||
int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
|
||||
u32 addr, u32 val);
|
||||
#endif /* __CXGB4_H__ */
|
||||
|
|
|
|||
|
|
@ -148,15 +148,6 @@ static unsigned int pfvfres_pmask(struct adapter *adapter,
|
|||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
MEMWIN0_APERTURE = 65536,
|
||||
MEMWIN0_BASE = 0x30000,
|
||||
MEMWIN1_APERTURE = 32768,
|
||||
MEMWIN1_BASE = 0x28000,
|
||||
MEMWIN2_APERTURE = 2048,
|
||||
MEMWIN2_BASE = 0x1b800,
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_TXQ_ENTRIES = 16384,
|
||||
MAX_CTRL_TXQ_ENTRIES = 1024,
|
||||
|
|
@ -371,6 +362,15 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
|
|||
uhash | mhash, sleep);
|
||||
}
|
||||
|
||||
int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */
|
||||
module_param(dbfifo_int_thresh, int, 0644);
|
||||
MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold");
|
||||
|
||||
int dbfifo_drain_delay = 1000; /* usecs to sleep while draining the dbfifo */
|
||||
module_param(dbfifo_drain_delay, int, 0644);
|
||||
MODULE_PARM_DESC(dbfifo_drain_delay,
|
||||
"usecs to sleep while draining the dbfifo");
|
||||
|
||||
/*
|
||||
* Set Rx properties of a port, such as promiscruity, address filters, and MTU.
|
||||
* If @mtu is -1 it is left unchanged.
|
||||
|
|
@ -389,6 +389,8 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct workqueue_struct *workq;
|
||||
|
||||
/**
|
||||
* link_start - enable a port
|
||||
* @dev: the port to enable
|
||||
|
|
@ -2196,7 +2198,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
|
|||
adap->tid_release_head = (void **)((uintptr_t)p | chan);
|
||||
if (!adap->tid_release_task_busy) {
|
||||
adap->tid_release_task_busy = true;
|
||||
schedule_work(&adap->tid_release_task);
|
||||
queue_work(workq, &adap->tid_release_task);
|
||||
}
|
||||
spin_unlock_bh(&adap->tid_release_lock);
|
||||
}
|
||||
|
|
@ -2366,6 +2368,16 @@ unsigned int cxgb4_port_chan(const struct net_device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(cxgb4_port_chan);
|
||||
|
||||
unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(dev);
|
||||
u32 v;
|
||||
|
||||
v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
|
||||
return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v);
|
||||
}
|
||||
EXPORT_SYMBOL(cxgb4_dbfifo_count);
|
||||
|
||||
/**
|
||||
* cxgb4_port_viid - get the VI id of a port
|
||||
* @dev: the net device for the port
|
||||
|
|
@ -2413,6 +2425,59 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
|
|||
}
|
||||
EXPORT_SYMBOL(cxgb4_iscsi_init);
|
||||
|
||||
int cxgb4_flush_eq_cache(struct net_device *dev)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(dev);
|
||||
int ret;
|
||||
|
||||
ret = t4_fwaddrspace_write(adap, adap->mbox,
|
||||
0xe1000000 + A_SGE_CTXT_CMD, 0x20000000);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cxgb4_flush_eq_cache);
|
||||
|
||||
static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
|
||||
{
|
||||
u32 addr = t4_read_reg(adap, A_SGE_DBQ_CTXT_BADDR) + 24 * qid + 8;
|
||||
__be64 indices;
|
||||
int ret;
|
||||
|
||||
ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
|
||||
if (!ret) {
|
||||
indices = be64_to_cpu(indices);
|
||||
*cidx = (indices >> 25) & 0xffff;
|
||||
*pidx = (indices >> 9) & 0xffff;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx,
|
||||
u16 size)
|
||||
{
|
||||
struct adapter *adap = netdev2adap(dev);
|
||||
u16 hw_pidx, hw_cidx;
|
||||
int ret;
|
||||
|
||||
ret = read_eq_indices(adap, qid, &hw_pidx, &hw_cidx);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (pidx != hw_pidx) {
|
||||
u16 delta;
|
||||
|
||||
if (pidx >= hw_pidx)
|
||||
delta = pidx - hw_pidx;
|
||||
else
|
||||
delta = size - hw_pidx + pidx;
|
||||
wmb();
|
||||
t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
|
||||
V_QID(qid) | V_PIDX(delta));
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cxgb4_sync_txq_pidx);
|
||||
|
||||
static struct pci_driver cxgb4_driver;
|
||||
|
||||
static void check_neigh_update(struct neighbour *neigh)
|
||||
|
|
@ -2446,6 +2511,144 @@ static struct notifier_block cxgb4_netevent_nb = {
|
|||
.notifier_call = netevent_cb
|
||||
};
|
||||
|
||||
static void drain_db_fifo(struct adapter *adap, int usecs)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
do {
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout(usecs_to_jiffies(usecs));
|
||||
v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
|
||||
if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
|
||||
break;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static void disable_txq_db(struct sge_txq *q)
|
||||
{
|
||||
spin_lock_irq(&q->db_lock);
|
||||
q->db_disabled = 1;
|
||||
spin_unlock_irq(&q->db_lock);
|
||||
}
|
||||
|
||||
static void enable_txq_db(struct sge_txq *q)
|
||||
{
|
||||
spin_lock_irq(&q->db_lock);
|
||||
q->db_disabled = 0;
|
||||
spin_unlock_irq(&q->db_lock);
|
||||
}
|
||||
|
||||
static void disable_dbs(struct adapter *adap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_ethrxq(&adap->sge, i)
|
||||
disable_txq_db(&adap->sge.ethtxq[i].q);
|
||||
for_each_ofldrxq(&adap->sge, i)
|
||||
disable_txq_db(&adap->sge.ofldtxq[i].q);
|
||||
for_each_port(adap, i)
|
||||
disable_txq_db(&adap->sge.ctrlq[i].q);
|
||||
}
|
||||
|
||||
static void enable_dbs(struct adapter *adap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_ethrxq(&adap->sge, i)
|
||||
enable_txq_db(&adap->sge.ethtxq[i].q);
|
||||
for_each_ofldrxq(&adap->sge, i)
|
||||
enable_txq_db(&adap->sge.ofldtxq[i].q);
|
||||
for_each_port(adap, i)
|
||||
enable_txq_db(&adap->sge.ctrlq[i].q);
|
||||
}
|
||||
|
||||
static void sync_txq_pidx(struct adapter *adap, struct sge_txq *q)
|
||||
{
|
||||
u16 hw_pidx, hw_cidx;
|
||||
int ret;
|
||||
|
||||
spin_lock_bh(&q->db_lock);
|
||||
ret = read_eq_indices(adap, (u16)q->cntxt_id, &hw_pidx, &hw_cidx);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (q->db_pidx != hw_pidx) {
|
||||
u16 delta;
|
||||
|
||||
if (q->db_pidx >= hw_pidx)
|
||||
delta = q->db_pidx - hw_pidx;
|
||||
else
|
||||
delta = q->size - hw_pidx + q->db_pidx;
|
||||
wmb();
|
||||
t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
|
||||
V_QID(q->cntxt_id) | V_PIDX(delta));
|
||||
}
|
||||
out:
|
||||
q->db_disabled = 0;
|
||||
spin_unlock_bh(&q->db_lock);
|
||||
if (ret)
|
||||
CH_WARN(adap, "DB drop recovery failed.\n");
|
||||
}
|
||||
static void recover_all_queues(struct adapter *adap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_ethrxq(&adap->sge, i)
|
||||
sync_txq_pidx(adap, &adap->sge.ethtxq[i].q);
|
||||
for_each_ofldrxq(&adap->sge, i)
|
||||
sync_txq_pidx(adap, &adap->sge.ofldtxq[i].q);
|
||||
for_each_port(adap, i)
|
||||
sync_txq_pidx(adap, &adap->sge.ctrlq[i].q);
|
||||
}
|
||||
|
||||
static void notify_rdma_uld(struct adapter *adap, enum cxgb4_control cmd)
|
||||
{
|
||||
mutex_lock(&uld_mutex);
|
||||
if (adap->uld_handle[CXGB4_ULD_RDMA])
|
||||
ulds[CXGB4_ULD_RDMA].control(adap->uld_handle[CXGB4_ULD_RDMA],
|
||||
cmd);
|
||||
mutex_unlock(&uld_mutex);
|
||||
}
|
||||
|
||||
static void process_db_full(struct work_struct *work)
|
||||
{
|
||||
struct adapter *adap;
|
||||
|
||||
adap = container_of(work, struct adapter, db_full_task);
|
||||
|
||||
notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
|
||||
drain_db_fifo(adap, dbfifo_drain_delay);
|
||||
t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
|
||||
F_DBFIFO_HP_INT | F_DBFIFO_LP_INT,
|
||||
F_DBFIFO_HP_INT | F_DBFIFO_LP_INT);
|
||||
notify_rdma_uld(adap, CXGB4_CONTROL_DB_EMPTY);
|
||||
}
|
||||
|
||||
static void process_db_drop(struct work_struct *work)
|
||||
{
|
||||
struct adapter *adap;
|
||||
|
||||
adap = container_of(work, struct adapter, db_drop_task);
|
||||
|
||||
t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0);
|
||||
disable_dbs(adap);
|
||||
notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
|
||||
drain_db_fifo(adap, 1);
|
||||
recover_all_queues(adap);
|
||||
enable_dbs(adap);
|
||||
}
|
||||
|
||||
void t4_db_full(struct adapter *adap)
|
||||
{
|
||||
t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
|
||||
F_DBFIFO_HP_INT | F_DBFIFO_LP_INT, 0);
|
||||
queue_work(workq, &adap->db_full_task);
|
||||
}
|
||||
|
||||
void t4_db_dropped(struct adapter *adap)
|
||||
{
|
||||
queue_work(workq, &adap->db_drop_task);
|
||||
}
|
||||
|
||||
static void uld_attach(struct adapter *adap, unsigned int uld)
|
||||
{
|
||||
void *handle;
|
||||
|
|
@ -2479,6 +2682,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
|
|||
lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
|
||||
lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
|
||||
lli.fw_vers = adap->params.fw_vers;
|
||||
lli.dbfifo_int_thresh = dbfifo_int_thresh;
|
||||
|
||||
handle = ulds[uld].add(&lli);
|
||||
if (IS_ERR(handle)) {
|
||||
|
|
@ -2649,6 +2853,8 @@ static void cxgb_down(struct adapter *adapter)
|
|||
{
|
||||
t4_intr_disable(adapter);
|
||||
cancel_work_sync(&adapter->tid_release_task);
|
||||
cancel_work_sync(&adapter->db_full_task);
|
||||
cancel_work_sync(&adapter->db_drop_task);
|
||||
adapter->tid_release_task_busy = false;
|
||||
adapter->tid_release_head = NULL;
|
||||
|
||||
|
|
@ -3593,6 +3799,7 @@ static int __devinit init_one(struct pci_dev *pdev,
|
|||
|
||||
adapter->pdev = pdev;
|
||||
adapter->pdev_dev = &pdev->dev;
|
||||
adapter->mbox = func;
|
||||
adapter->fn = func;
|
||||
adapter->msg_enable = dflt_msg_enable;
|
||||
memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
|
||||
|
|
@ -3601,6 +3808,8 @@ static int __devinit init_one(struct pci_dev *pdev,
|
|||
spin_lock_init(&adapter->tid_release_lock);
|
||||
|
||||
INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
|
||||
INIT_WORK(&adapter->db_full_task, process_db_full);
|
||||
INIT_WORK(&adapter->db_drop_task, process_db_drop);
|
||||
|
||||
err = t4_prep_adapter(adapter);
|
||||
if (err)
|
||||
|
|
@ -3788,6 +3997,10 @@ static int __init cxgb4_init_module(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
workq = create_singlethread_workqueue("cxgb4");
|
||||
if (!workq)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Debugfs support is optional, just warn if this fails */
|
||||
cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
if (!cxgb4_debugfs_root)
|
||||
|
|
@ -3803,6 +4016,8 @@ static void __exit cxgb4_cleanup_module(void)
|
|||
{
|
||||
pci_unregister_driver(&cxgb4_driver);
|
||||
debugfs_remove(cxgb4_debugfs_root); /* NULL ok */
|
||||
flush_workqueue(workq);
|
||||
destroy_workqueue(workq);
|
||||
}
|
||||
|
||||
module_init(cxgb4_init_module);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,12 @@ enum cxgb4_state {
|
|||
CXGB4_STATE_DETACH
|
||||
};
|
||||
|
||||
enum cxgb4_control {
|
||||
CXGB4_CONTROL_DB_FULL,
|
||||
CXGB4_CONTROL_DB_EMPTY,
|
||||
CXGB4_CONTROL_DB_DROP,
|
||||
};
|
||||
|
||||
struct pci_dev;
|
||||
struct l2t_data;
|
||||
struct net_device;
|
||||
|
|
@ -212,6 +218,7 @@ struct cxgb4_lld_info {
|
|||
unsigned short ucq_density; /* # of user CQs/page */
|
||||
void __iomem *gts_reg; /* address of GTS register */
|
||||
void __iomem *db_reg; /* address of kernel doorbell */
|
||||
int dbfifo_int_thresh; /* doorbell fifo int threshold */
|
||||
};
|
||||
|
||||
struct cxgb4_uld_info {
|
||||
|
|
@ -220,11 +227,13 @@ struct cxgb4_uld_info {
|
|||
int (*rx_handler)(void *handle, const __be64 *rsp,
|
||||
const struct pkt_gl *gl);
|
||||
int (*state_change)(void *handle, enum cxgb4_state new_state);
|
||||
int (*control)(void *handle, enum cxgb4_control control, ...);
|
||||
};
|
||||
|
||||
int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
|
||||
int cxgb4_unregister_uld(enum cxgb4_uld type);
|
||||
int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
|
||||
unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
|
||||
unsigned int cxgb4_port_chan(const struct net_device *dev);
|
||||
unsigned int cxgb4_port_viid(const struct net_device *dev);
|
||||
unsigned int cxgb4_port_idx(const struct net_device *dev);
|
||||
|
|
@ -236,4 +245,6 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
|
|||
const unsigned int *pgsz_order);
|
||||
struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
|
||||
unsigned int skb_len, unsigned int pull_len);
|
||||
int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
|
||||
int cxgb4_flush_eq_cache(struct net_device *dev);
|
||||
#endif /* !__CXGB4_OFLD_H */
|
||||
|
|
|
|||
|
|
@ -767,8 +767,13 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q,
|
|||
static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
|
||||
{
|
||||
wmb(); /* write descriptors before telling HW */
|
||||
t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
|
||||
QID(q->cntxt_id) | PIDX(n));
|
||||
spin_lock(&q->db_lock);
|
||||
if (!q->db_disabled) {
|
||||
t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
|
||||
V_QID(q->cntxt_id) | V_PIDX(n));
|
||||
}
|
||||
q->db_pidx = q->pidx;
|
||||
spin_unlock(&q->db_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2081,6 +2086,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
|
|||
q->stops = q->restarts = 0;
|
||||
q->stat = (void *)&q->desc[q->size];
|
||||
q->cntxt_id = id;
|
||||
spin_lock_init(&q->db_lock);
|
||||
adap->sge.egr_map[id - adap->sge.egr_start] = q;
|
||||
}
|
||||
|
||||
|
|
@ -2415,6 +2421,18 @@ void t4_sge_init(struct adapter *adap)
|
|||
RXPKTCPLMODE |
|
||||
(STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
|
||||
|
||||
/*
|
||||
* Set up to drop DOORBELL writes when the DOORBELL FIFO overflows
|
||||
* and generate an interrupt when this occurs so we can recover.
|
||||
*/
|
||||
t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
|
||||
V_HP_INT_THRESH(M_HP_INT_THRESH) |
|
||||
V_LP_INT_THRESH(M_LP_INT_THRESH),
|
||||
V_HP_INT_THRESH(dbfifo_int_thresh) |
|
||||
V_LP_INT_THRESH(dbfifo_int_thresh));
|
||||
t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP,
|
||||
F_ENABLE_DROP);
|
||||
|
||||
for (i = v = 0; i < 32; i += 4)
|
||||
v |= (PAGE_SHIFT - 10) << i;
|
||||
t4_write_reg(adap, SGE_HOST_PAGE_SIZE, v);
|
||||
|
|
|
|||
|
|
@ -868,11 +868,14 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
|
|||
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
||||
}
|
||||
|
||||
typedef void (*int_handler_t)(struct adapter *adap);
|
||||
|
||||
struct intr_info {
|
||||
unsigned int mask; /* bits to check in interrupt status */
|
||||
const char *msg; /* message to print or NULL */
|
||||
short stat_idx; /* stat counter to increment or -1 */
|
||||
unsigned short fatal; /* whether the condition reported is fatal */
|
||||
int_handler_t int_handler; /* platform-specific int handler */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -905,6 +908,8 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
|
|||
} else if (acts->msg && printk_ratelimit())
|
||||
dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
|
||||
status & acts->mask);
|
||||
if (acts->int_handler)
|
||||
acts->int_handler(adapter);
|
||||
mask |= acts->mask;
|
||||
}
|
||||
status &= mask;
|
||||
|
|
@ -1013,7 +1018,9 @@ static void sge_intr_handler(struct adapter *adapter)
|
|||
{ ERR_INVALID_CIDX_INC,
|
||||
"SGE GTS CIDX increment too large", -1, 0 },
|
||||
{ ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
|
||||
{ ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
|
||||
{ F_DBFIFO_LP_INT, NULL, -1, 0, t4_db_full },
|
||||
{ F_DBFIFO_HP_INT, NULL, -1, 0, t4_db_full },
|
||||
{ F_ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped },
|
||||
{ ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
|
||||
"SGE IQID > 1023 received CPL for FL", -1, 0 },
|
||||
{ ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
|
||||
|
|
@ -1034,10 +1041,10 @@ static void sge_intr_handler(struct adapter *adapter)
|
|||
};
|
||||
|
||||
v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) |
|
||||
((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
|
||||
((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
|
||||
if (v) {
|
||||
dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
|
||||
(unsigned long long)v);
|
||||
(unsigned long long)v);
|
||||
t4_write_reg(adapter, SGE_INT_CAUSE1, v);
|
||||
t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
|
||||
}
|
||||
|
|
@ -1513,6 +1520,7 @@ void t4_intr_enable(struct adapter *adapter)
|
|||
ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
|
||||
ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
|
||||
ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
|
||||
F_DBFIFO_HP_INT | F_DBFIFO_LP_INT |
|
||||
EGRESS_SIZE_ERR);
|
||||
t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
|
||||
t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
|
||||
|
|
@ -1986,6 +1994,54 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
|
|||
(var).retval_len16 = htonl(FW_LEN16(var)); \
|
||||
} while (0)
|
||||
|
||||
int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
|
||||
u32 addr, u32 val)
|
||||
{
|
||||
struct fw_ldst_cmd c;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST |
|
||||
F_FW_CMD_WRITE |
|
||||
V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE));
|
||||
c.cycles_to_len16 = htonl(FW_LEN16(c));
|
||||
c.u.addrval.addr = htonl(addr);
|
||||
c.u.addrval.val = htonl(val);
|
||||
|
||||
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* t4_mem_win_read_len - read memory through PCIE memory window
|
||||
* @adap: the adapter
|
||||
* @addr: address of first byte requested aligned on 32b.
|
||||
* @data: len bytes to hold the data read
|
||||
* @len: amount of data to read from window. Must be <=
|
||||
* MEMWIN0_APERATURE after adjusting for 16B alignment
|
||||
* requirements of the the memory window.
|
||||
*
|
||||
* Read len bytes of data from MC starting at @addr.
|
||||
*/
|
||||
int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
|
||||
{
|
||||
int i;
|
||||
int off;
|
||||
|
||||
/*
|
||||
* Align on a 16B boundary.
|
||||
*/
|
||||
off = addr & 15;
|
||||
if ((addr & 3) || (len + off) > MEMWIN0_APERTURE)
|
||||
return -EINVAL;
|
||||
|
||||
t4_write_reg(adap, A_PCIE_MEM_ACCESS_OFFSET, addr & ~15);
|
||||
t4_read_reg(adap, A_PCIE_MEM_ACCESS_OFFSET);
|
||||
|
||||
for (i = 0; i < len; i += 4)
|
||||
*data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_mdio_rd - read a PHY register through MDIO
|
||||
* @adap: the adapter
|
||||
|
|
|
|||
|
|
@ -190,6 +190,59 @@
|
|||
#define SGE_DEBUG_DATA_LOW 0x10d4
|
||||
#define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
|
||||
|
||||
#define S_LP_INT_THRESH 12
|
||||
#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
|
||||
#define S_HP_INT_THRESH 28
|
||||
#define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH)
|
||||
#define A_SGE_DBFIFO_STATUS 0x10a4
|
||||
|
||||
#define S_ENABLE_DROP 13
|
||||
#define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP)
|
||||
#define F_ENABLE_DROP V_ENABLE_DROP(1U)
|
||||
#define A_SGE_DOORBELL_CONTROL 0x10a8
|
||||
|
||||
#define A_SGE_CTXT_CMD 0x11fc
|
||||
#define A_SGE_DBQ_CTXT_BADDR 0x1084
|
||||
|
||||
#define A_SGE_PF_KDOORBELL 0x0
|
||||
|
||||
#define S_QID 15
|
||||
#define V_QID(x) ((x) << S_QID)
|
||||
|
||||
#define S_PIDX 0
|
||||
#define V_PIDX(x) ((x) << S_PIDX)
|
||||
|
||||
#define M_LP_COUNT 0x7ffU
|
||||
#define S_LP_COUNT 0
|
||||
#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
|
||||
|
||||
#define M_HP_COUNT 0x7ffU
|
||||
#define S_HP_COUNT 16
|
||||
#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
|
||||
|
||||
#define A_SGE_INT_ENABLE3 0x1040
|
||||
|
||||
#define S_DBFIFO_HP_INT 8
|
||||
#define V_DBFIFO_HP_INT(x) ((x) << S_DBFIFO_HP_INT)
|
||||
#define F_DBFIFO_HP_INT V_DBFIFO_HP_INT(1U)
|
||||
|
||||
#define S_DBFIFO_LP_INT 7
|
||||
#define V_DBFIFO_LP_INT(x) ((x) << S_DBFIFO_LP_INT)
|
||||
#define F_DBFIFO_LP_INT V_DBFIFO_LP_INT(1U)
|
||||
|
||||
#define S_DROPPED_DB 0
|
||||
#define V_DROPPED_DB(x) ((x) << S_DROPPED_DB)
|
||||
#define F_DROPPED_DB V_DROPPED_DB(1U)
|
||||
|
||||
#define S_ERR_DROPPED_DB 18
|
||||
#define V_ERR_DROPPED_DB(x) ((x) << S_ERR_DROPPED_DB)
|
||||
#define F_ERR_DROPPED_DB V_ERR_DROPPED_DB(1U)
|
||||
|
||||
#define A_PCIE_MEM_ACCESS_OFFSET 0x306c
|
||||
|
||||
#define M_HP_INT_THRESH 0xfU
|
||||
#define M_LP_INT_THRESH 0xfU
|
||||
|
||||
#define PCIE_PF_CLI 0x44
|
||||
#define PCIE_INT_CAUSE 0x3004
|
||||
#define UNXSPLCPLERR 0x20000000U
|
||||
|
|
|
|||
|
|
@ -1620,4 +1620,19 @@ struct fw_hdr {
|
|||
#define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
|
||||
#define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
|
||||
#define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff)
|
||||
|
||||
#define S_FW_CMD_OP 24
|
||||
#define V_FW_CMD_OP(x) ((x) << S_FW_CMD_OP)
|
||||
|
||||
#define S_FW_CMD_REQUEST 23
|
||||
#define V_FW_CMD_REQUEST(x) ((x) << S_FW_CMD_REQUEST)
|
||||
#define F_FW_CMD_REQUEST V_FW_CMD_REQUEST(1U)
|
||||
|
||||
#define S_FW_CMD_WRITE 21
|
||||
#define V_FW_CMD_WRITE(x) ((x) << S_FW_CMD_WRITE)
|
||||
#define F_FW_CMD_WRITE V_FW_CMD_WRITE(1U)
|
||||
|
||||
#define S_FW_LDST_CMD_ADDRSPACE 0
|
||||
#define V_FW_LDST_CMD_ADDRSPACE(x) ((x) << S_FW_LDST_CMD_ADDRSPACE)
|
||||
|
||||
#endif /* _T4FW_INTERFACE_H_ */
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
obj-$(CONFIG_BE2NET) += be2net.o
|
||||
|
||||
be2net-y := be_main.o be_cmds.o be_ethtool.o
|
||||
be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/u64_stats_sync.h>
|
||||
|
||||
#include "be_hw.h"
|
||||
#include "be_roce.h"
|
||||
|
||||
#define DRV_VER "4.2.220u"
|
||||
#define DRV_NAME "be2net"
|
||||
|
|
@ -102,7 +103,8 @@ static inline char *nic_name(struct pci_dev *pdev)
|
|||
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
|
||||
|
||||
#define MAX_TX_QS 8
|
||||
#define MAX_MSIX_VECTORS MAX_RSS_QS
|
||||
#define MAX_ROCE_EQS 5
|
||||
#define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */
|
||||
#define BE_TX_BUDGET 256
|
||||
#define BE_NAPI_WEIGHT 64
|
||||
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
|
||||
|
|
@ -405,6 +407,17 @@ struct be_adapter {
|
|||
u32 tx_fc; /* Tx flow control */
|
||||
bool stats_cmd_sent;
|
||||
u8 generation; /* BladeEngine ASIC generation */
|
||||
u32 if_type;
|
||||
struct {
|
||||
u8 __iomem *base; /* Door Bell */
|
||||
u32 size;
|
||||
u32 total_size;
|
||||
u64 io_addr;
|
||||
} roce_db;
|
||||
u32 num_msix_roce_vec;
|
||||
struct ocrdma_dev *ocrdma_dev;
|
||||
struct list_head entry;
|
||||
|
||||
u32 flash_status;
|
||||
struct completion flash_compl;
|
||||
|
||||
|
|
@ -441,6 +454,10 @@ struct be_adapter {
|
|||
#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
|
||||
(adapter->pdev->device == OC_DEVICE_ID4))
|
||||
|
||||
#define be_roce_supported(adapter) ((adapter->if_type == SLI_INTF_TYPE_3 || \
|
||||
adapter->sli_family == SKYHAWK_SLI_FAMILY) && \
|
||||
(adapter->function_mode & RDMA_ENABLED))
|
||||
|
||||
extern const struct ethtool_ops be_ethtool_ops;
|
||||
|
||||
#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
|
||||
|
|
@ -597,6 +614,12 @@ static inline bool be_is_wol_excluded(struct be_adapter *adapter)
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool be_type_2_3(struct be_adapter *adapter)
|
||||
{
|
||||
return (adapter->if_type == SLI_INTF_TYPE_2 ||
|
||||
adapter->if_type == SLI_INTF_TYPE_3) ? true : false;
|
||||
}
|
||||
|
||||
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
|
||||
u16 num_popped);
|
||||
extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
|
||||
|
|
@ -606,4 +629,16 @@ extern bool be_is_wol_supported(struct be_adapter *adapter);
|
|||
extern bool be_pause_supported(struct be_adapter *adapter);
|
||||
extern u32 be_get_fw_log_level(struct be_adapter *adapter);
|
||||
|
||||
/*
|
||||
* internal function to initialize-cleanup roce device.
|
||||
*/
|
||||
extern void be_roce_dev_add(struct be_adapter *);
|
||||
extern void be_roce_dev_remove(struct be_adapter *);
|
||||
|
||||
/*
|
||||
* internal function to open-close roce device during ifup-ifdown.
|
||||
*/
|
||||
extern void be_roce_dev_open(struct be_adapter *);
|
||||
extern void be_roce_dev_close(struct be_adapter *);
|
||||
|
||||
#endif /* BE_H */
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "be.h"
|
||||
#include "be_cmds.h"
|
||||
|
||||
|
|
@ -2646,3 +2647,41 @@ err:
|
|||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
|
||||
int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
|
||||
{
|
||||
struct be_adapter *adapter = netdev_priv(netdev_handle);
|
||||
struct be_mcc_wrb *wrb;
|
||||
struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *) wrb_payload;
|
||||
struct be_cmd_req_hdr *req;
|
||||
struct be_cmd_resp_hdr *resp;
|
||||
int status;
|
||||
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
status = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
req = embedded_payload(wrb);
|
||||
resp = embedded_payload(wrb);
|
||||
|
||||
be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
|
||||
hdr->opcode, wrb_payload_size, wrb, NULL);
|
||||
memcpy(req, wrb_payload, wrb_payload_size);
|
||||
be_dws_cpu_to_le(req, wrb_payload_size);
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
if (cmd_status)
|
||||
*cmd_status = (status & 0xffff);
|
||||
if (ext_status)
|
||||
*ext_status = 0;
|
||||
memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
|
||||
be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
|
||||
err:
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(be_roce_mcc_cmd);
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,7 @@ struct be_cmd_resp_modify_eq_delay {
|
|||
/* The HW can come up in either of the following multi-channel modes
|
||||
* based on the skew/IPL.
|
||||
*/
|
||||
#define RDMA_ENABLED 0x4
|
||||
#define FLEX10_MODE 0x400
|
||||
#define VNIC_MODE 0x20000
|
||||
#define UMC_ENABLED 0x1000000
|
||||
|
|
|
|||
|
|
@ -100,11 +100,13 @@
|
|||
#define SLI_INTF_REV_SHIFT 4
|
||||
#define SLI_INTF_FT_MASK 0x00000001
|
||||
|
||||
#define SLI_INTF_TYPE_2 2
|
||||
#define SLI_INTF_TYPE_3 3
|
||||
|
||||
/* SLI family */
|
||||
#define BE_SLI_FAMILY 0x0
|
||||
#define LANCER_A0_SLI_FAMILY 0xA
|
||||
|
||||
#define SKYHAWK_SLI_FAMILY 0x2
|
||||
|
||||
/********* ISR0 Register offset **********/
|
||||
#define CEV_ISR0_OFFSET 0xC18
|
||||
|
|
|
|||
|
|
@ -2151,10 +2151,17 @@ static uint be_num_rss_want(struct be_adapter *adapter)
|
|||
static void be_msix_enable(struct be_adapter *adapter)
|
||||
{
|
||||
#define BE_MIN_MSIX_VECTORS 1
|
||||
int i, status, num_vec;
|
||||
int i, status, num_vec, num_roce_vec = 0;
|
||||
|
||||
/* If RSS queues are not used, need a vec for default RX Q */
|
||||
num_vec = min(be_num_rss_want(adapter), num_online_cpus());
|
||||
if (be_roce_supported(adapter)) {
|
||||
num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS,
|
||||
(num_online_cpus() + 1));
|
||||
num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS);
|
||||
num_vec += num_roce_vec;
|
||||
num_vec = min(num_vec, MAX_MSIX_VECTORS);
|
||||
}
|
||||
num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
|
||||
|
||||
for (i = 0; i < num_vec; i++)
|
||||
|
|
@ -2171,7 +2178,17 @@ static void be_msix_enable(struct be_adapter *adapter)
|
|||
}
|
||||
return;
|
||||
done:
|
||||
adapter->num_msix_vec = num_vec;
|
||||
if (be_roce_supported(adapter)) {
|
||||
if (num_vec > num_roce_vec) {
|
||||
adapter->num_msix_vec = num_vec - num_roce_vec;
|
||||
adapter->num_msix_roce_vec =
|
||||
num_vec - adapter->num_msix_vec;
|
||||
} else {
|
||||
adapter->num_msix_vec = num_vec;
|
||||
adapter->num_msix_roce_vec = 0;
|
||||
}
|
||||
} else
|
||||
adapter->num_msix_vec = num_vec;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2283,6 +2300,8 @@ static int be_close(struct net_device *netdev)
|
|||
struct be_eq_obj *eqo;
|
||||
int i;
|
||||
|
||||
be_roce_dev_close(adapter);
|
||||
|
||||
be_async_mcc_disable(adapter);
|
||||
|
||||
if (!lancer_chip(adapter))
|
||||
|
|
@ -2391,6 +2410,7 @@ static int be_open(struct net_device *netdev)
|
|||
if (!status)
|
||||
be_link_status_update(adapter, link_status);
|
||||
|
||||
be_roce_dev_open(adapter);
|
||||
return 0;
|
||||
err:
|
||||
be_close(adapter->netdev);
|
||||
|
|
@ -3232,6 +3252,24 @@ static void be_unmap_pci_bars(struct be_adapter *adapter)
|
|||
iounmap(adapter->csr);
|
||||
if (adapter->db)
|
||||
iounmap(adapter->db);
|
||||
if (adapter->roce_db.base)
|
||||
pci_iounmap(adapter->pdev, adapter->roce_db.base);
|
||||
}
|
||||
|
||||
static int lancer_roce_map_pci_bars(struct be_adapter *adapter)
|
||||
{
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
u8 __iomem *addr;
|
||||
|
||||
addr = pci_iomap(pdev, 2, 0);
|
||||
if (addr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
adapter->roce_db.base = addr;
|
||||
adapter->roce_db.io_addr = pci_resource_start(pdev, 2);
|
||||
adapter->roce_db.size = 8192;
|
||||
adapter->roce_db.total_size = pci_resource_len(pdev, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int be_map_pci_bars(struct be_adapter *adapter)
|
||||
|
|
@ -3240,11 +3278,18 @@ static int be_map_pci_bars(struct be_adapter *adapter)
|
|||
int db_reg;
|
||||
|
||||
if (lancer_chip(adapter)) {
|
||||
addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0),
|
||||
pci_resource_len(adapter->pdev, 0));
|
||||
if (addr == NULL)
|
||||
return -ENOMEM;
|
||||
adapter->db = addr;
|
||||
if (be_type_2_3(adapter)) {
|
||||
addr = ioremap_nocache(
|
||||
pci_resource_start(adapter->pdev, 0),
|
||||
pci_resource_len(adapter->pdev, 0));
|
||||
if (addr == NULL)
|
||||
return -ENOMEM;
|
||||
adapter->db = addr;
|
||||
}
|
||||
if (adapter->if_type == SLI_INTF_TYPE_3) {
|
||||
if (lancer_roce_map_pci_bars(adapter))
|
||||
goto pci_map_err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3269,14 +3314,19 @@ static int be_map_pci_bars(struct be_adapter *adapter)
|
|||
if (addr == NULL)
|
||||
goto pci_map_err;
|
||||
adapter->db = addr;
|
||||
|
||||
if (adapter->sli_family == SKYHAWK_SLI_FAMILY) {
|
||||
adapter->roce_db.size = 4096;
|
||||
adapter->roce_db.io_addr =
|
||||
pci_resource_start(adapter->pdev, db_reg);
|
||||
adapter->roce_db.total_size =
|
||||
pci_resource_len(adapter->pdev, db_reg);
|
||||
}
|
||||
return 0;
|
||||
pci_map_err:
|
||||
be_unmap_pci_bars(adapter);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
static void be_ctrl_cleanup(struct be_adapter *adapter)
|
||||
{
|
||||
struct be_dma_mem *mem = &adapter->mbox_mem_alloced;
|
||||
|
|
@ -3382,6 +3432,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
|
|||
if (!adapter)
|
||||
return;
|
||||
|
||||
be_roce_dev_remove(adapter);
|
||||
|
||||
unregister_netdev(adapter->netdev);
|
||||
|
||||
be_clear(adapter);
|
||||
|
|
@ -3495,17 +3547,27 @@ static int be_dev_type_check(struct be_adapter *adapter)
|
|||
break;
|
||||
case BE_DEVICE_ID2:
|
||||
case OC_DEVICE_ID2:
|
||||
case OC_DEVICE_ID5:
|
||||
adapter->generation = BE_GEN3;
|
||||
break;
|
||||
case OC_DEVICE_ID3:
|
||||
case OC_DEVICE_ID4:
|
||||
pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
|
||||
adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
|
||||
SLI_INTF_IF_TYPE_SHIFT;
|
||||
if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
|
||||
SLI_INTF_IF_TYPE_SHIFT;
|
||||
|
||||
if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
|
||||
if_type != 0x02) {
|
||||
!be_type_2_3(adapter)) {
|
||||
dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
|
||||
SLI_INTF_FAMILY_SHIFT);
|
||||
adapter->generation = BE_GEN3;
|
||||
break;
|
||||
case OC_DEVICE_ID5:
|
||||
pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
|
||||
if ((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) {
|
||||
dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -3774,6 +3836,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
|
|||
if (status != 0)
|
||||
goto unsetup;
|
||||
|
||||
be_roce_dev_add(adapter);
|
||||
|
||||
dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
|
||||
adapter->port_num);
|
||||
|
||||
|
|
|
|||
182
drivers/net/ethernet/emulex/benet/be_roce.c
Normal file
182
drivers/net/ethernet/emulex/benet/be_roce.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (C) 2005 - 2011 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation. The full GNU General
|
||||
* Public License is included in this distribution in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* linux-drivers@emulex.com
|
||||
*
|
||||
* Emulex
|
||||
* 3333 Susan Street
|
||||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "be.h"
|
||||
#include "be_cmds.h"
|
||||
|
||||
static struct ocrdma_driver *ocrdma_drv;
|
||||
static LIST_HEAD(be_adapter_list);
|
||||
static DEFINE_MUTEX(be_adapter_list_lock);
|
||||
|
||||
static void _be_roce_dev_add(struct be_adapter *adapter)
|
||||
{
|
||||
struct be_dev_info dev_info;
|
||||
int i, num_vec;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
|
||||
if (!ocrdma_drv)
|
||||
return;
|
||||
if (pdev->device == OC_DEVICE_ID5) {
|
||||
/* only msix is supported on these devices */
|
||||
if (!msix_enabled(adapter))
|
||||
return;
|
||||
/* DPP region address and length */
|
||||
dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2);
|
||||
dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2);
|
||||
} else {
|
||||
dev_info.dpp_unmapped_addr = 0;
|
||||
dev_info.dpp_unmapped_len = 0;
|
||||
}
|
||||
dev_info.pdev = adapter->pdev;
|
||||
if (adapter->sli_family == SKYHAWK_SLI_FAMILY)
|
||||
dev_info.db = adapter->db;
|
||||
else
|
||||
dev_info.db = adapter->roce_db.base;
|
||||
dev_info.unmapped_db = adapter->roce_db.io_addr;
|
||||
dev_info.db_page_size = adapter->roce_db.size;
|
||||
dev_info.db_total_size = adapter->roce_db.total_size;
|
||||
dev_info.netdev = adapter->netdev;
|
||||
memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN);
|
||||
dev_info.dev_family = adapter->sli_family;
|
||||
if (msix_enabled(adapter)) {
|
||||
/* provide all the vectors, so that EQ creation response
|
||||
* can decide which one to use.
|
||||
*/
|
||||
num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
|
||||
dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;
|
||||
dev_info.msix.num_vectors = min(num_vec, MAX_ROCE_MSIX_VECTORS);
|
||||
/* provide start index of the vector,
|
||||
* so in case of linear usage,
|
||||
* it can use the base as starting point.
|
||||
*/
|
||||
dev_info.msix.start_vector = adapter->num_evt_qs;
|
||||
for (i = 0; i < dev_info.msix.num_vectors; i++) {
|
||||
dev_info.msix.vector_list[i] =
|
||||
adapter->msix_entries[i].vector;
|
||||
}
|
||||
} else {
|
||||
dev_info.msix.num_vectors = 0;
|
||||
dev_info.intr_mode = BE_INTERRUPT_MODE_INTX;
|
||||
}
|
||||
adapter->ocrdma_dev = ocrdma_drv->add(&dev_info);
|
||||
}
|
||||
|
||||
void be_roce_dev_add(struct be_adapter *adapter)
|
||||
{
|
||||
if (be_roce_supported(adapter)) {
|
||||
INIT_LIST_HEAD(&adapter->entry);
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
list_add_tail(&adapter->entry, &be_adapter_list);
|
||||
|
||||
/* invoke add() routine of roce driver only if
|
||||
* valid driver registered with add method and add() is not yet
|
||||
* invoked on a given adapter.
|
||||
*/
|
||||
_be_roce_dev_add(adapter);
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void _be_roce_dev_remove(struct be_adapter *adapter)
|
||||
{
|
||||
if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev)
|
||||
ocrdma_drv->remove(adapter->ocrdma_dev);
|
||||
adapter->ocrdma_dev = NULL;
|
||||
}
|
||||
|
||||
void be_roce_dev_remove(struct be_adapter *adapter)
|
||||
{
|
||||
if (be_roce_supported(adapter)) {
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
_be_roce_dev_remove(adapter);
|
||||
list_del(&adapter->entry);
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void _be_roce_dev_open(struct be_adapter *adapter)
|
||||
{
|
||||
if (ocrdma_drv && adapter->ocrdma_dev &&
|
||||
ocrdma_drv->state_change_handler)
|
||||
ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0);
|
||||
}
|
||||
|
||||
void be_roce_dev_open(struct be_adapter *adapter)
|
||||
{
|
||||
if (be_roce_supported(adapter)) {
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
_be_roce_dev_open(adapter);
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void _be_roce_dev_close(struct be_adapter *adapter)
|
||||
{
|
||||
if (ocrdma_drv && adapter->ocrdma_dev &&
|
||||
ocrdma_drv->state_change_handler)
|
||||
ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1);
|
||||
}
|
||||
|
||||
void be_roce_dev_close(struct be_adapter *adapter)
|
||||
{
|
||||
if (be_roce_supported(adapter)) {
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
_be_roce_dev_close(adapter);
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
}
|
||||
}
|
||||
|
||||
int be_roce_register_driver(struct ocrdma_driver *drv)
|
||||
{
|
||||
struct be_adapter *dev;
|
||||
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
if (ocrdma_drv) {
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
ocrdma_drv = drv;
|
||||
list_for_each_entry(dev, &be_adapter_list, entry) {
|
||||
struct net_device *netdev;
|
||||
_be_roce_dev_add(dev);
|
||||
netdev = dev->netdev;
|
||||
if (netif_running(netdev) && netif_oper_up(netdev))
|
||||
_be_roce_dev_open(dev);
|
||||
}
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(be_roce_register_driver);
|
||||
|
||||
void be_roce_unregister_driver(struct ocrdma_driver *drv)
|
||||
{
|
||||
struct be_adapter *dev;
|
||||
|
||||
mutex_lock(&be_adapter_list_lock);
|
||||
list_for_each_entry(dev, &be_adapter_list, entry) {
|
||||
if (dev->ocrdma_dev)
|
||||
_be_roce_dev_remove(dev);
|
||||
}
|
||||
ocrdma_drv = NULL;
|
||||
mutex_unlock(&be_adapter_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(be_roce_unregister_driver);
|
||||
75
drivers/net/ethernet/emulex/benet/be_roce.h
Normal file
75
drivers/net/ethernet/emulex/benet/be_roce.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2005 - 2011 Emulex
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation. The full GNU General
|
||||
* Public License is included in this distribution in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* linux-drivers@emulex.com
|
||||
*
|
||||
* Emulex
|
||||
* 3333 Susan Street
|
||||
* Costa Mesa, CA 92626
|
||||
*/
|
||||
|
||||
#ifndef BE_ROCE_H
|
||||
#define BE_ROCE_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct ocrdma_dev;
|
||||
|
||||
enum be_interrupt_mode {
|
||||
BE_INTERRUPT_MODE_MSIX = 0,
|
||||
BE_INTERRUPT_MODE_INTX = 1,
|
||||
BE_INTERRUPT_MODE_MSI = 2,
|
||||
};
|
||||
|
||||
#define MAX_ROCE_MSIX_VECTORS 16
|
||||
struct be_dev_info {
|
||||
u8 __iomem *db;
|
||||
u64 unmapped_db;
|
||||
u32 db_page_size;
|
||||
u32 db_total_size;
|
||||
u64 dpp_unmapped_addr;
|
||||
u32 dpp_unmapped_len;
|
||||
struct pci_dev *pdev;
|
||||
struct net_device *netdev;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u32 dev_family;
|
||||
enum be_interrupt_mode intr_mode;
|
||||
struct {
|
||||
int num_vectors;
|
||||
int start_vector;
|
||||
u32 vector_list[MAX_ROCE_MSIX_VECTORS];
|
||||
} msix;
|
||||
};
|
||||
|
||||
/* ocrdma driver register's the callback functions with nic driver. */
|
||||
struct ocrdma_driver {
|
||||
unsigned char name[32];
|
||||
struct ocrdma_dev *(*add) (struct be_dev_info *dev_info);
|
||||
void (*remove) (struct ocrdma_dev *);
|
||||
void (*state_change_handler) (struct ocrdma_dev *, u32 new_state);
|
||||
};
|
||||
|
||||
enum {
|
||||
BE_DEV_UP = 0,
|
||||
BE_DEV_DOWN = 1
|
||||
};
|
||||
|
||||
/* APIs for RoCE driver to register callback handlers,
|
||||
* which will be invoked when device is added, removed, ifup, ifdown
|
||||
*/
|
||||
int be_roce_register_driver(struct ocrdma_driver *drv);
|
||||
void be_roce_unregister_driver(struct ocrdma_driver *drv);
|
||||
|
||||
/* API for RoCE driver to issue mailbox commands */
|
||||
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
|
||||
int wrb_payload_size, u16 *cmd_status, u16 *ext_status);
|
||||
|
||||
#endif /* BE_ROCE_H */
|
||||
|
|
@ -124,9 +124,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
|
|||
|
||||
spin_lock(&bitmap->lock);
|
||||
bitmap_clear(bitmap->table, obj, cnt);
|
||||
bitmap->last = min(bitmap->last, obj);
|
||||
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
|
||||
& bitmap->mask;
|
||||
bitmap->avail += cnt;
|
||||
spin_unlock(&bitmap->lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,20 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags)
|
|||
mlx4_dbg(dev, " %s\n", fname[i]);
|
||||
}
|
||||
|
||||
static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
|
||||
{
|
||||
static const char * const fname[] = {
|
||||
[0] = "RSS support",
|
||||
[1] = "RSS Toeplitz Hash Function support",
|
||||
[2] = "RSS XOR Hash Function support"
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fname); ++i)
|
||||
if (fname[i] && (flags & (1LL << i)))
|
||||
mlx4_dbg(dev, " %s\n", fname[i]);
|
||||
}
|
||||
|
||||
int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
|
||||
{
|
||||
struct mlx4_cmd_mailbox *mailbox;
|
||||
|
|
@ -346,6 +360,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
#define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29
|
||||
#define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b
|
||||
#define QUERY_DEV_CAP_MAX_GSO_OFFSET 0x2d
|
||||
#define QUERY_DEV_CAP_RSS_OFFSET 0x2e
|
||||
#define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f
|
||||
#define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33
|
||||
#define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35
|
||||
|
|
@ -390,6 +405,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
#define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98
|
||||
#define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0
|
||||
|
||||
dev_cap->flags2 = 0;
|
||||
mailbox = mlx4_alloc_cmd_mailbox(dev);
|
||||
if (IS_ERR(mailbox))
|
||||
return PTR_ERR(mailbox);
|
||||
|
|
@ -439,6 +455,17 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
else
|
||||
dev_cap->max_gso_sz = 1 << field;
|
||||
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSS_OFFSET);
|
||||
if (field & 0x20)
|
||||
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_XOR;
|
||||
if (field & 0x10)
|
||||
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_TOP;
|
||||
field &= 0xf;
|
||||
if (field) {
|
||||
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS;
|
||||
dev_cap->max_rss_tbl_sz = 1 << field;
|
||||
} else
|
||||
dev_cap->max_rss_tbl_sz = 0;
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RDMA_OFFSET);
|
||||
dev_cap->max_rdma_global = 1 << (field & 0x3f);
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET);
|
||||
|
|
@ -632,8 +659,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg);
|
||||
mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz);
|
||||
mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters);
|
||||
mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz);
|
||||
|
||||
dump_dev_cap_flags(dev, dev_cap->flags);
|
||||
dump_dev_cap_flags2(dev, dev_cap->flags2);
|
||||
|
||||
out:
|
||||
mlx4_free_cmd_mailbox(dev, mailbox);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ struct mlx4_dev_cap {
|
|||
u64 trans_code[MLX4_MAX_PORTS + 1];
|
||||
u16 stat_rate_support;
|
||||
u64 flags;
|
||||
u64 flags2;
|
||||
int reserved_uars;
|
||||
int uar_size;
|
||||
int min_page_sz;
|
||||
|
|
@ -110,6 +111,7 @@ struct mlx4_dev_cap {
|
|||
u32 reserved_lkey;
|
||||
u64 max_icm_sz;
|
||||
int max_gso_sz;
|
||||
int max_rss_tbl_sz;
|
||||
u8 supported_port_types[MLX4_MAX_PORTS + 1];
|
||||
u8 suggested_type[MLX4_MAX_PORTS + 1];
|
||||
u8 default_sense[MLX4_MAX_PORTS + 1];
|
||||
|
|
|
|||
|
|
@ -272,10 +272,12 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
|||
dev->caps.max_msg_sz = dev_cap->max_msg_sz;
|
||||
dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1);
|
||||
dev->caps.flags = dev_cap->flags;
|
||||
dev->caps.flags2 = dev_cap->flags2;
|
||||
dev->caps.bmme_flags = dev_cap->bmme_flags;
|
||||
dev->caps.reserved_lkey = dev_cap->reserved_lkey;
|
||||
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
|
||||
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
|
||||
dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz;
|
||||
|
||||
/* Sense port always allowed on supported devices for ConnectX1 and 2 */
|
||||
if (dev->pdev->device != 0x1003)
|
||||
|
|
|
|||
Loading…
Reference in a new issue