Commit 34b2aafe authored by Bryan O'Sullivan's avatar Bryan O'Sullivan Committed by Roland Dreier

IB/ipath: simplify layering code

A lot of ipath layer code was only called in one place. Now that the
ipath_core and ib_ipath drivers are merged, it's more sensible to simply
inline the simple stuff that the layer code was doing.
Signed-off-by: default avatarBryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent b1c1b6a3
......@@ -45,7 +45,6 @@
#include <asm/uaccess.h>
#include "ipath_kernel.h"
#include "ipath_layer.h"
#include "ipath_common.h"
int ipath_diag_inuse;
......
......@@ -39,7 +39,6 @@
#include <linux/vmalloc.h>
#include "ipath_kernel.h"
#include "ipath_layer.h"
#include "ipath_verbs.h"
#include "ipath_common.h"
......@@ -508,7 +507,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
ipathfs_add_device(dd);
ipath_user_add(dd);
ipath_diag_add(dd);
ipath_layer_add(dd);
ipath_register_ib_device(dd);
goto bail;
......@@ -539,7 +537,6 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
dd = pci_get_drvdata(pdev);
ipath_unregister_ib_device(dd->verbs_dev);
ipath_layer_remove(dd);
ipath_diag_remove(dd);
ipath_user_remove(dd);
ipathfs_remove_device(dd);
......@@ -614,11 +611,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
*
* wait up to msecs milliseconds for IB link state change to occur for
* now, take the easy polling route. Currently used only by
* ipath_layer_set_linkstate. Returns 0 if state reached, otherwise
* ipath_set_linkstate. Returns 0 if state reached, otherwise
* -ETIMEDOUT state can have multiple states set, for any of several
* transitions.
*/
int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs)
static int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state,
int msecs)
{
dd->ipath_sma_state_wanted = state;
wait_event_interruptible_timeout(ipath_sma_state_wait,
......@@ -814,58 +812,6 @@ bail:
return skb;
}
/**
* ipath_rcv_layer - receive a packet for the layered (ethernet) driver
* @dd: the infinipath device
* @etail: the sk_buff number
* @tlen: the total packet length
* @hdr: the ethernet header
*
* Separate routine for better overall optimization
*/
static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail,
u32 tlen, struct ether_header *hdr)
{
u32 elen;
u8 pad, *bthbytes;
struct sk_buff *skb, *nskb;
if (dd->ipath_port0_skbs &&
hdr->sub_opcode == IPATH_ITH4X_OPCODE_ENCAP) {
/*
* Allocate a new sk_buff to replace the one we give
* to the network stack.
*/
nskb = ipath_alloc_skb(dd, GFP_ATOMIC);
if (!nskb) {
/* count OK packets that we drop */
ipath_stats.sps_krdrops++;
return;
}
bthbytes = (u8 *) hdr->bth;
pad = (bthbytes[1] >> 4) & 3;
/* +CRC32 */
elen = tlen - (sizeof(*hdr) + pad + sizeof(u32));
skb = dd->ipath_port0_skbs[etail];
dd->ipath_port0_skbs[etail] = nskb;
skb_put(skb, elen);
dd->ipath_f_put_tid(dd, etail + (u64 __iomem *)
((char __iomem *) dd->ipath_kregbase
+ dd->ipath_rcvegrbase), 0,
virt_to_phys(nskb->data));
__ipath_layer_rcv(dd, hdr, skb);
/* another ether packet received */
ipath_stats.sps_ether_rpkts++;
}
else if (hdr->sub_opcode == IPATH_ITH4X_OPCODE_LID_ARP)
__ipath_layer_rcv_lid(dd, hdr);
}
static void ipath_rcv_hdrerr(struct ipath_devdata *dd,
u32 eflags,
u32 l,
......@@ -979,22 +925,17 @@ reloop:
if (unlikely(eflags))
ipath_rcv_hdrerr(dd, eflags, l, etail, rc);
else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
ipath_ib_rcv(dd->verbs_dev, rc + 1, ebuf,
tlen);
if (dd->ipath_lli_counter)
dd->ipath_lli_counter--;
} else if (etype == RCVHQ_RCV_TYPE_EAGER) {
if (qp == IPATH_KD_QP &&
bthbytes[0] == ipath_layer_rcv_opcode &&
ebuf)
ipath_rcv_layer(dd, etail, tlen,
(struct ether_header *)hdr);
else
ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
"qp=%x), len %x; ignored\n",
etype, bthbytes[0], qp, tlen);
ipath_ib_rcv(dd->verbs_dev, rc + 1, ebuf, tlen);
if (dd->ipath_lli_counter)
dd->ipath_lli_counter--;
ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
"qp=%x), len %x; ignored\n",
etype, bthbytes[0], qp, tlen);
}
else if (etype == RCVHQ_RCV_TYPE_EAGER)
ipath_cdbg(PKT, "typ %x, opcode %x (eager, "
"qp=%x), len %x; ignored\n",
etype, bthbytes[0], qp, tlen);
else if (etype == RCVHQ_RCV_TYPE_EXPECTED)
ipath_dbg("Bug: Expected TID, opcode %x; ignored\n",
be32_to_cpu(hdr->bth[0]) & 0xff);
......@@ -1320,13 +1261,6 @@ rescan:
goto bail;
}
if (updated)
/*
* ran out of bufs, now some (at least this one we just
* got) are now available, so tell the layered driver.
*/
__ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE);
/*
* set next starting place. Since it's just an optimization,
* it doesn't matter who wins on this, so no locking
......@@ -1503,7 +1437,7 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
return ret;
}
void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
{
static const char *what[4] = {
[0] = "DOWN",
......@@ -1537,6 +1471,180 @@ void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
dd->ipath_ibcctrl | which);
}
int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
{
u32 lstate;
int ret;
switch (newstate) {
case IPATH_IB_LINKDOWN:
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
/* don't wait */
ret = 0;
goto bail;
case IPATH_IB_LINKDOWN_SLEEP:
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_SLEEP <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
/* don't wait */
ret = 0;
goto bail;
case IPATH_IB_LINKDOWN_DISABLE:
ipath_set_ib_lstate(dd,
INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
/* don't wait */
ret = 0;
goto bail;
case IPATH_IB_LINKINIT:
if (dd->ipath_flags & IPATH_LINKINIT) {
ret = 0;
goto bail;
}
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT <<
INFINIPATH_IBCC_LINKCMD_SHIFT);
lstate = IPATH_LINKINIT;
break;
case IPATH_IB_LINKARM:
if (dd->ipath_flags & IPATH_LINKARMED) {
ret = 0;
goto bail;
}
if (!(dd->ipath_flags &
(IPATH_LINKINIT | IPATH_LINKACTIVE))) {
ret = -EINVAL;
goto bail;
}
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ARMED <<
INFINIPATH_IBCC_LINKCMD_SHIFT);
/*
* Since the port can transition to ACTIVE by receiving
* a non VL 15 packet, wait for either state.
*/
lstate = IPATH_LINKARMED | IPATH_LINKACTIVE;
break;
case IPATH_IB_LINKACTIVE:
if (dd->ipath_flags & IPATH_LINKACTIVE) {
ret = 0;
goto bail;
}
if (!(dd->ipath_flags & IPATH_LINKARMED)) {
ret = -EINVAL;
goto bail;
}
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_ACTIVE <<
INFINIPATH_IBCC_LINKCMD_SHIFT);
lstate = IPATH_LINKACTIVE;
break;
default:
ipath_dbg("Invalid linkstate 0x%x requested\n", newstate);
ret = -EINVAL;
goto bail;
}
ret = ipath_wait_linkstate(dd, lstate, 2000);
bail:
return ret;
}
/**
* ipath_set_mtu - set the MTU
* @dd: the infinipath device
* @arg: the new MTU
*
* we can handle "any" incoming size, the issue here is whether we
* need to restrict our outgoing size. For now, we don't do any
* sanity checking on this, and we don't deal with what happens to
* programs that are already running when the size changes.
* NOTE: changing the MTU will usually cause the IBC to go back to
* link initialize (IPATH_IBSTATE_INIT) state...
*/
int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
{
u32 piosize;
int changed = 0;
int ret;
/*
* mtu is IB data payload max. It's the largest power of 2 less
* than piosize (or even larger, since it only really controls the
* largest we can receive; we can send the max of the mtu and
* piosize). We check that it's one of the valid IB sizes.
*/
if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 &&
arg != 4096) {
ipath_dbg("Trying to set invalid mtu %u, failing\n", arg);
ret = -EINVAL;
goto bail;
}
if (dd->ipath_ibmtu == arg) {
ret = 0; /* same as current */
goto bail;
}
piosize = dd->ipath_ibmaxlen;
dd->ipath_ibmtu = arg;
if (arg >= (piosize - IPATH_PIO_MAXIBHDR)) {
/* Only if it's not the initial value (or reset to it) */
if (piosize != dd->ipath_init_ibmaxlen) {
dd->ipath_ibmaxlen = piosize;
changed = 1;
}
} else if ((arg + IPATH_PIO_MAXIBHDR) != dd->ipath_ibmaxlen) {
piosize = arg + IPATH_PIO_MAXIBHDR;
ipath_cdbg(VERBOSE, "ibmaxlen was 0x%x, setting to 0x%x "
"(mtu 0x%x)\n", dd->ipath_ibmaxlen, piosize,
arg);
dd->ipath_ibmaxlen = piosize;
changed = 1;
}
if (changed) {
/*
* set the IBC maxpktlength to the size of our pio
* buffers in words
*/
u64 ibc = dd->ipath_ibcctrl;
ibc &= ~(INFINIPATH_IBCC_MAXPKTLEN_MASK <<
INFINIPATH_IBCC_MAXPKTLEN_SHIFT);
piosize = piosize - 2 * sizeof(u32); /* ignore pbc */
dd->ipath_ibmaxlen = piosize;
piosize /= sizeof(u32); /* in words */
/*
* for ICRC, which we only send in diag test pkt mode, and
* we don't need to worry about that for mtu
*/
piosize += 1;
ibc |= piosize << INFINIPATH_IBCC_MAXPKTLEN_SHIFT;
dd->ipath_ibcctrl = ibc;
ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
dd->ipath_ibcctrl);
dd->ipath_f_tidtemplate(dd);
}
ret = 0;
bail:
return ret;
}
int ipath_set_lid(struct ipath_devdata *dd, u32 arg, u8 lmc)
{
dd->ipath_lid = arg;
dd->ipath_lmc = lmc;
return 0;
}
/**
* ipath_read_kreg64_port - read a device's per-port 64-bit kernel register
* @dd: the infinipath device
......@@ -1640,13 +1748,6 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
/*
* we are shutting down, so tell the layered driver. We don't do
* this on just a link state change, much like ethernet, a cable
* unplug, etc. doesn't change driver state
*/
ipath_layer_intr(dd, IPATH_LAYER_INT_IF_DOWN);
/* disable IBC */
dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
......
......@@ -39,7 +39,6 @@
#include <asm/pgtable.h>
#include "ipath_kernel.h"
#include "ipath_layer.h"
#include "ipath_common.h"
static int ipath_open(struct inode *, struct file *);
......
......@@ -34,7 +34,6 @@
#include <linux/pci.h>
#include "ipath_kernel.h"
#include "ipath_layer.h"
#include "ipath_verbs.h"
#include "ipath_common.h"
......@@ -290,8 +289,6 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
*dd->ipath_statusp |=
IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF;
dd->ipath_f_setextled(dd, lstate, ltstate);
__ipath_layer_intr(dd, IPATH_LAYER_INT_IF_UP);
} else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) {
/*
* set INIT and DOWN. Down is checked by most of the other
......@@ -709,10 +706,6 @@ static void handle_layer_pioavail(struct ipath_devdata *dd)
{
int ret;
ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE);
if (ret > 0)
goto set;
ret = ipath_ib_piobufavail(dd->verbs_dev);
if (ret > 0)
goto set;
......
......@@ -518,16 +518,6 @@ extern struct list_head ipath_dev_list;
extern spinlock_t ipath_devs_lock;
extern struct ipath_devdata *ipath_lookup(int unit);
extern u16 ipath_layer_rcv_opcode;
extern int __ipath_layer_intr(struct ipath_devdata *, u32);
extern int ipath_layer_intr(struct ipath_devdata *, u32);
extern int __ipath_layer_rcv(struct ipath_devdata *, void *,
struct sk_buff *);
extern int __ipath_layer_rcv_lid(struct ipath_devdata *, void *);
void ipath_layer_add(struct ipath_devdata *);
void ipath_layer_remove(struct ipath_devdata *);
int ipath_init_chip(struct ipath_devdata *, int);
int ipath_enable_wc(struct ipath_devdata *dd);
void ipath_disable_wc(struct ipath_devdata *dd);
......@@ -575,12 +565,13 @@ void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);
int ipath_parse_ushort(const char *str, unsigned short *valp);
int ipath_wait_linkstate(struct ipath_devdata *, u32, int);
void ipath_set_ib_lstate(struct ipath_devdata *, int);
void ipath_kreceive(struct ipath_devdata *);
int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned);
int ipath_reset_device(int);
void ipath_get_faststats(unsigned long);
int ipath_set_linkstate(struct ipath_devdata *, u8);
int ipath_set_mtu(struct ipath_devdata *, u16);
int ipath_set_lid(struct ipath_devdata *, u32, u8);
/* for use in system calls, where we want to know device type, etc. */
#define port_fp(fp) ((struct ipath_portdata *) (fp)->private_data)
......
This diff is collapsed.
......@@ -40,73 +40,9 @@
*/
struct sk_buff;
struct ipath_sge_state;
struct ipath_devdata;
struct ether_header;
struct ipath_layer_counters {
u64 symbol_error_counter;
u64 link_error_recovery_counter;
u64 link_downed_counter;
u64 port_rcv_errors;
u64 port_rcv_remphys_errors;
u64 port_xmit_discards;
u64 port_xmit_data;
u64 port_rcv_data;
u64 port_xmit_packets;
u64 port_rcv_packets;
u32 local_link_integrity_errors;
u32 excessive_buffer_overrun_errors;
};
/*
* A segment is a linear region of low physical memory.
* XXX Maybe we should use phys addr here and kmap()/kunmap().
* Used by the verbs layer.
*/
struct ipath_seg {
void *vaddr;
size_t length;
};
/* The number of ipath_segs that fit in a page. */
#define IPATH_SEGSZ (PAGE_SIZE / sizeof (struct ipath_seg))
struct ipath_segarray {
struct ipath_seg segs[IPATH_SEGSZ];
};
struct ipath_mregion {
u64 user_base; /* User's address for this region */
u64 iova; /* IB start address of this region */
size_t length;
u32 lkey;
u32 offset; /* offset (bytes) to start of region */
int access_flags;
u32 max_segs; /* number of ipath_segs in all the arrays */
u32 mapsz; /* size of the map array */
struct ipath_segarray *map[0]; /* the segments */
};
/*
* These keep track of the copy progress within a memory region.
* Used by the verbs layer.
*/
struct ipath_sge {
struct ipath_mregion *mr;
void *vaddr; /* current pointer into the segment */
u32 sge_length; /* length of the SGE */
u32 length; /* remaining length of the segment */
u16 m; /* current index: mr->map[m] */
u16 n; /* current index: mr->map[m]->segs[n] */
};
struct ipath_sge_state {
struct ipath_sge *sg_list; /* next SGE to be used if any */
struct ipath_sge sge; /* progress state for the current SGE */
u8 num_sge;
};
int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *),
void (*l_remove)(void *),
int (*l_intr)(void *, u32),
......@@ -119,49 +55,9 @@ int ipath_layer_open(struct ipath_devdata *, u32 * pktmax);
u16 ipath_layer_get_lid(struct ipath_devdata *dd);
int ipath_layer_get_mac(struct ipath_devdata *dd, u8 *);
u16 ipath_layer_get_bcast(struct ipath_devdata *dd);
u32 ipath_layer_get_cr_errpkey(struct ipath_devdata *dd);
int ipath_layer_set_linkstate(struct ipath_devdata *dd, u8 state);
int ipath_layer_set_mtu(struct ipath_devdata *, u16);
int ipath_set_lid(struct ipath_devdata *, u32, u8);
int ipath_layer_send_hdr(struct ipath_devdata *dd,
struct ether_header *hdr);
int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
u32 * hdr, u32 len, struct ipath_sge_state *ss);
int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd);
int ipath_layer_get_boardname(struct ipath_devdata *dd, char *name,
size_t namelen);
int ipath_layer_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
u64 *rwords, u64 *spkts, u64 *rpkts,
u64 *xmit_wait);
int ipath_layer_get_counters(struct ipath_devdata *dd,
struct ipath_layer_counters *cntrs);
int ipath_layer_want_buffer(struct ipath_devdata *dd);
int ipath_layer_set_guid(struct ipath_devdata *, __be64 guid);
__be64 ipath_layer_get_guid(struct ipath_devdata *);
u32 ipath_layer_get_majrev(struct ipath_devdata *);
u32 ipath_layer_get_minrev(struct ipath_devdata *);
u32 ipath_layer_get_pcirev(struct ipath_devdata *);
u32 ipath_layer_get_flags(struct ipath_devdata *dd);
struct device *ipath_layer_get_device(struct ipath_devdata *dd);
u16 ipath_layer_get_deviceid(struct ipath_devdata *dd);
u32 ipath_layer_get_vendorid(struct ipath_devdata *);
u64 ipath_layer_get_lastibcstat(struct ipath_devdata *dd);
u32 ipath_layer_get_ibmtu(struct ipath_devdata *dd);
int ipath_layer_enable_timer(struct ipath_devdata *dd);
int ipath_layer_disable_timer(struct ipath_devdata *dd);
int ipath_layer_set_verbs_flags(struct ipath_devdata *dd, unsigned flags);
unsigned ipath_layer_get_npkeys(struct ipath_devdata *dd);
unsigned ipath_layer_get_pkey(struct ipath_devdata *dd, unsigned index);
int ipath_layer_get_pkeys(struct ipath_devdata *dd, u16 *pkeys);
int ipath_layer_set_pkeys(struct ipath_devdata *dd, u16 *pkeys);
int ipath_layer_get_linkdowndefaultstate(struct ipath_devdata *dd);
int ipath_layer_set_linkdowndefaultstate(struct ipath_devdata *dd,
int sleep);
int ipath_layer_get_phyerrthreshold(struct ipath_devdata *dd);
int ipath_layer_set_phyerrthreshold(struct ipath_devdata *dd, unsigned n);
int ipath_layer_get_overrunthreshold(struct ipath_devdata *dd);
int ipath_layer_set_overrunthreshold(struct ipath_devdata *dd, unsigned n);
u32 ipath_layer_get_rcvhdrentsize(struct ipath_devdata *dd);
/* ipath_ether interrupt values */
#define IPATH_LAYER_INT_IF_UP 0x2
......
This diff is collapsed.
......@@ -36,6 +36,18 @@
#include "ipath_verbs.h"
/* Fast memory region */
struct ipath_fmr {
struct ib_fmr ibfmr;
u8 page_shift;
struct ipath_mregion mr; /* must be last */
};
static inline struct ipath_fmr *to_ifmr(struct ib_fmr *ibfmr)
{
return container_of(ibfmr, struct ipath_fmr, ibfmr);
}
/**
* ipath_get_dma_mr - get a DMA memory region
* @pd: protection domain for this memory region
......
......@@ -461,7 +461,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto inval;
if (attr_mask & IB_QP_PKEY_INDEX)
if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd))
if (attr->pkey_index >= ipath_get_npkeys(dev->dd))
goto inval;
if (attr_mask & IB_QP_MIN_RNR_TIMER)
......@@ -644,6 +644,33 @@ __be32 ipath_compute_aeth(struct ipath_qp *qp)
return cpu_to_be32(aeth);
}
/**
* set_verbs_flags - set the verbs layer flags
* @dd: the infinipath device
* @flags: the flags to set
*/
static int set_verbs_flags(struct ipath_devdata *dd, unsigned flags)
{
struct ipath_devdata *ss;
unsigned long lflags;
spin_lock_irqsave(&ipath_devs_lock, lflags);
list_for_each_entry(ss, &ipath_dev_list, ipath_list) {
if (!(ss->ipath_flags & IPATH_INITTED))
continue;
if ((flags & IPATH_VERBS_KERNEL_SMA) &&
!(*ss->ipath_statusp & IPATH_STATUS_SMA))
*ss->ipath_statusp |= IPATH_STATUS_OIB_SMA;
else
*ss->ipath_statusp &= ~IPATH_STATUS_OIB_SMA;
}
spin_unlock_irqrestore(&ipath_devs_lock, lflags);
return 0;
}
/**
* ipath_create_qp - create a queue pair for a device
* @ibpd: the protection domain who's device we create the queue pair for
......@@ -760,8 +787,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
/* Tell the core driver that the kernel SMA is present. */
if (init_attr->qp_type == IB_QPT_SMI)
ipath_layer_set_verbs_flags(dev->dd,
IPATH_VERBS_KERNEL_SMA);
set_verbs_flags(dev->dd, IPATH_VERBS_KERNEL_SMA);
break;
default:
......@@ -838,7 +864,7 @@ int ipath_destroy_qp(struct ib_qp *ibqp)
/* Tell the core driver that the kernel SMA is gone. */
if (qp->ibqp.qp_type == IB_QPT_SMI)
ipath_layer_set_verbs_flags(dev->dd, 0);
set_verbs_flags(dev->dd, 0);
spin_lock_irqsave(&qp->s_lock, flags);
qp->state = IB_QPS_ERR;
......
......@@ -32,7 +32,7 @@
*/
#include "ipath_verbs.h"
#include "ipath_common.h"
#include "ipath_kernel.h"
/* cut down ridiculously long IB macro names */
#define OP(x) IB_OPCODE_RC_##x
......@@ -540,7 +540,7 @@ static void send_rc_ack(struct ipath_qp *qp)
lrh0 = IPATH_LRH_GRH;
}
/* read pkey_index w/o lock (its atomic) */
bth0 = ipath_layer_get_pkey(dev->dd, qp->s_pkey_index);
bth0 = ipath_get_pkey(dev->dd, qp->s_pkey_index);
if (qp->r_nak_state)
ohdr->u.aeth = cpu_to_be32((qp->r_msn & IPATH_MSN_MASK) |
(qp->r_nak_state <<
......@@ -557,7 +557,7 @@ static void send_rc_ack(struct ipath_qp *qp)
hdr.lrh[0] = cpu_to_be16(lrh0);
hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC);
hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd));
hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid);
ohdr->bth[0] = cpu_to_be32(bth0);
ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
ohdr->bth[2] = cpu_to_be32(qp->r_ack_psn & IPATH_PSN_MASK);
......@@ -1323,8 +1323,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
* the eager header buffer size to 56 bytes so the last 4
* bytes of the BTH header (PSN) is in the data buffer.
*/
header_in_data =
ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
if (header_in_data) {
psn = be32_to_cpu(((__be32 *) data)[0]);
data += sizeof(__be32);
......
......@@ -470,6 +470,15 @@ done:
wake_up(&qp->wait);
}
static int want_buffer(struct ipath_devdata *dd)
{
set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
dd->ipath_sendctrl);
return 0;
}
/**
* ipath_no_bufs_available - tell the layer driver we need buffers
* @qp: the QP that caused the problem
......@@ -486,7 +495,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
list_add_tail(&qp->piowait, &dev->piowait);
spin_unlock_irqrestore(&dev->pending_lock, flags);
/*
* Note that as soon as ipath_layer_want_buffer() is called and
* Note that as soon as want_buffer() is called and
* possibly before it returns, ipath_ib_piobufavail()
* could be called. If we are still in the tasklet function,
* tasklet_hi_schedule() will not call us until the next time
......@@ -496,7 +505,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
*/
clear_bit(IPATH_S_BUSY, &qp->s_flags);
tasklet_unlock(&qp->s_task);
ipath_layer_want_buffer(dev->dd);
want_buffer(dev->dd);
dev->n_piowait++;
}
......@@ -611,7 +620,7 @@ u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr,
hdr->hop_limit = grh->hop_limit;
/* The SGID is 32-bit aligned. */
hdr->sgid.global.subnet_prefix = dev->gid_prefix;
hdr->sgid.global.interface_id = ipath_layer_get_guid(dev->dd);
hdr->sgid.global.interface_id = dev->dd->ipath_guid;
hdr->dgid = grh->dgid;
/* GRH header size in 32-bit words. */
......@@ -643,8 +652,7 @@ void ipath_do_ruc_send(unsigned long data)
if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags))
goto bail;
if (unlikely(qp->remote_ah_attr.dlid ==
ipath_layer_get_lid(dev->dd))) {
if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) {
ipath_ruc_loopback(qp);
goto clear;
}
......@@ -711,8 +719,8 @@ again:
qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords +
SIZE_OF_CRC);
qp->s_hdr.lrh[3] = cpu_to_be16(ipath_layer_get_lid(dev->dd));
bth0 |= ipath_layer_get_pkey(dev->dd, qp->s_pkey_index);
qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid);
bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index);
bth0 |= extra_bytes << 20;
ohdr->bth[0] = cpu_to_be32(bth0);
ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
......
......@@ -35,7 +35,6 @@
#include <linux/pci.h>
#include "ipath_kernel.h"
#include "ipath_layer.h"
#include "ipath_common.h"
/**
......@@ -227,7 +226,6 @@ static ssize_t store_mlid(struct device *dev,
unit = dd->ipath_unit;
dd->ipath_mlid = mlid;
ipath_layer_intr(dd, IPATH_LAYER_INT_BCAST);
goto bail;
invalid:
......@@ -467,7 +465,7 @@ static ssize_t store_link_state(struct device *dev,
if (ret < 0)
goto invalid;
r = ipath_layer_set_linkstate(dd, state);
r = ipath_set_linkstate(dd, state);
if (r < 0) {
ret = r;
goto bail;
......@@ -502,7 +500,7 @@ static ssize_t store_mtu(struct device *dev,
if (ret < 0)
goto invalid;
r = ipath_layer_set_mtu(dd, mtu);
r = ipath_set_mtu(dd, mtu);
if (r < 0)
ret = r;
......
......@@ -32,7 +32,7 @@
*/
#include "ipath_verbs.h"
#include "ipath_common.h"
#include "ipath_kernel.h"
/* cut down ridiculously long IB macro names */
#define OP(x) IB_OPCODE_UC_##x
......@@ -261,8 +261,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
* size to 56 bytes so the last 4 bytes of
* the BTH header (PSN) is in the data buffer.
*/
header_in_data =
ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
if (header_in_data) {
psn = be32_to_cpu(((__be32 *) data)[0]);
data += sizeof(__be32);
......
......@@ -353,7 +353,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
ss.num_sge++;
}
/* Check for invalid packet size. */
if (len > ipath_layer_get_ibmtu(dev->dd)) {
if (len > dev->dd->ipath_ibmtu) {
ret = -EINVAL;
goto bail;
}
......@@ -375,7 +375,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
dev->n_unicast_xmit++;
lid = ah_attr->dlid &
~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1);
if (unlikely(lid == ipath_layer_get_lid(dev->dd))) {
if (unlikely(lid == dev->dd->ipath_lid)) {
/*
* Pass in an uninitialized ib_wc to save stack
* space.
......@@ -404,7 +404,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
qp->s_hdr.u.l.grh.sgid.global.subnet_prefix =
dev->gid_prefix;
qp->s_hdr.u.l.grh.sgid.global.interface_id =
ipath_layer_get_guid(dev->dd);
dev->dd->ipath_guid;
qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid;
/*
* Don't worry about sending to locally attached multicast
......@@ -434,7 +434,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
qp->s_hdr.lrh[0] = cpu_to_be16(lrh0);
qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */
qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC);
lid = ipath_layer_get_lid(dev->dd);
lid = dev->dd->ipath_lid;
if (lid) {
lid |= ah_attr->src_path_bits &
((1 << (dev->mkeyprot_resv_lmc & 7)) - 1);
......@@ -445,7 +445,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
bth0 |= 1 << 23;
bth0 |= extra_bytes << 20;
bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY :
ipath_layer_get_pkey(dev->dd, qp->s_pkey_index);
ipath_get_pkey(dev->dd, qp->s_pkey_index);
ohdr->bth[0] = cpu_to_be32(bth0);
/*
* Use the multicast QP if the destination LID is a multicast LID.
......@@ -531,8 +531,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
* the eager header buffer size to 56 bytes so the last 12
* bytes of the IB header is in the data buffer.
*/
header_in_data =
ipath_layer_get_rcvhdrentsize(dev->dd) == 16;
header_in_data = dev->dd->ipath_rcvhdrentsize == 16;
if (header_in_data) {
qkey = be32_to_cpu(((__be32 *) data)[1]);
src_qp = be32_to_cpu(((__be32 *) data)[2]);
......
This diff is collapsed.
......@@ -153,19 +153,6 @@ struct ipath_mcast {
int n_attached;
};
/* Memory region */
struct ipath_mr {
struct ib_mr ibmr;
struct ipath_mregion mr; /* must be last */
};
/* Fast memory region */
struct ipath_fmr {
struct ib_fmr ibfmr;
u8 page_shift;
struct ipath_mregion mr; /* must be last */
};
/* Protection domain */
struct ipath_pd {
struct ib_pd ibpd;
......@@ -216,6 +203,54 @@ struct ipath_cq {
struct ipath_mmap_info *ip;
};
/*
* A segment is a linear region of low physical memory.
* XXX Maybe we should use phys addr here and kmap()/kunmap().
* Used by the verbs layer.
*/
struct ipath_seg {
void *vaddr;
size_t length;
};
/* The number of ipath_segs that fit in a page. */
#define IPATH_SEGSZ (PAGE_SIZE / sizeof (struct ipath_seg))
struct ipath_segarray {
struct ipath_seg segs[IPATH_SEGSZ];
};
struct ipath_mregion {
u64 user_base; /* User's address for this region */
u64 iova; /* IB start address of this region */
size_t length;
u32 lkey;
u32 offset; /* offset (bytes) to start of region */
int access_flags;
u32 max_segs; /* number of ipath_segs in all the arrays */
u32 mapsz; /* size of the map array */
struct ipath_segarray *map[0]; /* the segments */
};
/*
* These keep track of the copy progress within a memory region.
* Used by the verbs layer.
*/
struct ipath_sge {
struct ipath_mregion *mr;
void *vaddr; /* current pointer into the segment */
u32 sge_length; /* length of the SGE */
u32 length; /* remaining length of the segment */
u16 m; /* current index: mr->map[m] */
u16 n; /* current index: mr->map[m]->segs[n] */
};
/* Memory region */
struct ipath_mr {
struct ib_mr ibmr;
struct ipath_mregion mr; /* must be last */
};
/*
* Send work request queue entry.
* The size of the sg_list is determined when the QP is created and stored
......@@ -270,6 +305,12 @@ struct ipath_srq {
u32 limit;
};
struct ipath_sge_state {
struct ipath_sge *sg_list; /* next SGE to be used if any */
struct ipath_sge sge; /* progress state for the current SGE */
u8 num_sge;
};
/*
* Variables prefixed with s_ are for the requester (sender).
* Variables prefixed with r_ are for the responder (receiver).
......@@ -500,8 +541,19 @@ struct ipath_ibdev {
struct ipath_opcode_stats opstats[128];
};
struct ipath_ucontext {
struct ib_ucontext ibucontext;
struct ipath_verbs_counters {
u64 symbol_error_counter;
u64 link_error_recovery_counter;
u64 link_downed_counter;
u64 port_rcv_errors;
u64 port_rcv_remphys_errors;
u64 port_xmit_discards;
u64 port_xmit_data;
u64 port_rcv_data;
u64 port_xmit_packets;
u64 port_rcv_packets;
u32 local_link_integrity_errors;
u32 excessive_buffer_overrun_errors;
};
static inline struct ipath_mr *to_imr(struct ib_mr *ibmr)
......@@ -509,11 +561,6 @@ static inline struct ipath_mr *to_imr(struct ib_mr *ibmr)
return container_of(ibmr, struct ipath_mr, ibmr);
}
static inline struct ipath_fmr *to_ifmr(struct ib_fmr *ibfmr)
{
return container_of(ibfmr, struct ipath_fmr, ibfmr);
}
static inline struct ipath_pd *to_ipd(struct ib_pd *ibpd)
{
return container_of(ibpd, struct ipath_pd, ibpd);
......@@ -551,12 +598,6 @@ int ipath_process_mad(struct ib_device *ibdev,
struct ib_grh *in_grh,
struct ib_mad *in_mad, struct ib_mad *out_mad);
static inline struct ipath_ucontext *to_iucontext(struct ib_ucontext
*ibucontext)
{
return container_of(ibucontext, struct ipath_ucontext, ibucontext);
}
/*
* Compare the lower 24 bits of the two values.
* Returns an integer <, ==, or > than zero.
......@@ -568,6 +609,13 @@ static inline int ipath_cmp24(u32 a, u32 b)
struct ipath_mcast *ipath_mcast_find(union ib_gid *mgid);
int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords,
u64 *rwords, u64 *spkts, u64 *rpkts,
u64 *xmit_wait);
int ipath_get_counters(struct ipath_devdata *dd,
struct ipath_verbs_counters *cntrs);
int ipath_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
......@@ -598,6 +646,9 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
u32 *hdr, u32 len, struct ipath_sge_state *ss);
void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
......@@ -721,6 +772,12 @@ int ipath_ib_piobufavail(struct ipath_ibdev *);
void ipath_ib_timer(struct ipath_ibdev *);
unsigned ipath_get_npkeys(struct ipath_devdata *);
u32 ipath_get_cr_errpkey(struct ipath_devdata *);
unsigned ipath_get_pkey(struct ipath_devdata *, unsigned);
extern const enum ib_wc_opcode ib_ipath_wc_opcode[];
extern const u8 ipath_cvt_physportstate[];
......
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