Commit dd286422 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  RDMA/cxgb3: Wrap the software send queue pointer as needed on flush
  IB/ipath: Change ipath_devdata.ipath_sdma_status to be unsigned long
  IB/ipath: Make ipath_portdata work with struct pid * not pid_t
  IB/ipath: Fix RDMA read response sequence checking
  IB/ipath: Fix many locking issues when switching to error state
  IB/ipath: Fix RC and UC error handling
  RDMA/nes: Fix up nes_lro_max_aggr module parameter
parents 4717df58 a58e58fa
...@@ -405,11 +405,11 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) ...@@ -405,11 +405,11 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2); struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2);
ptr = wq->sq_rptr + count; ptr = wq->sq_rptr + count;
sqp += count; sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
while (ptr != wq->sq_wptr) { while (ptr != wq->sq_wptr) {
insert_sq_cqe(wq, cq, sqp); insert_sq_cqe(wq, cq, sqp);
sqp++;
ptr++; ptr++;
sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
flushed++; flushed++;
} }
return flushed; return flushed;
......
...@@ -1894,7 +1894,7 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) ...@@ -1894,7 +1894,7 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
*/ */
if (dd->ipath_flags & IPATH_HAS_SEND_DMA) { if (dd->ipath_flags & IPATH_HAS_SEND_DMA) {
int skip_cancel; int skip_cancel;
u64 *statp = &dd->ipath_sdma_status; unsigned long *statp = &dd->ipath_sdma_status;
spin_lock_irqsave(&dd->ipath_sdma_lock, flags); spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
skip_cancel = skip_cancel =
...@@ -2616,7 +2616,7 @@ int ipath_reset_device(int unit) ...@@ -2616,7 +2616,7 @@ int ipath_reset_device(int unit)
ipath_dbg("unit %u port %d is in use " ipath_dbg("unit %u port %d is in use "
"(PID %u cmd %s), can't reset\n", "(PID %u cmd %s), can't reset\n",
unit, i, unit, i,
dd->ipath_pd[i]->port_pid, pid_nr(dd->ipath_pd[i]->port_pid),
dd->ipath_pd[i]->port_comm); dd->ipath_pd[i]->port_comm);
ret = -EBUSY; ret = -EBUSY;
goto bail; goto bail;
...@@ -2654,19 +2654,21 @@ int ipath_reset_device(int unit) ...@@ -2654,19 +2654,21 @@ int ipath_reset_device(int unit)
static int ipath_signal_procs(struct ipath_devdata *dd, int sig) static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
{ {
int i, sub, any = 0; int i, sub, any = 0;
pid_t pid; struct pid *pid;
if (!dd->ipath_pd) if (!dd->ipath_pd)
return 0; return 0;
for (i = 1; i < dd->ipath_cfgports; i++) { for (i = 1; i < dd->ipath_cfgports; i++) {
if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt || if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt)
!dd->ipath_pd[i]->port_pid)
continue; continue;
pid = dd->ipath_pd[i]->port_pid; pid = dd->ipath_pd[i]->port_pid;
if (!pid)
continue;
dev_info(&dd->pcidev->dev, "context %d in use " dev_info(&dd->pcidev->dev, "context %d in use "
"(PID %u), sending signal %d\n", "(PID %u), sending signal %d\n",
i, pid, sig); i, pid_nr(pid), sig);
kill_proc(pid, sig, 1); kill_pid(pid, sig, 1);
any++; any++;
for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) { for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) {
pid = dd->ipath_pd[i]->port_subpid[sub]; pid = dd->ipath_pd[i]->port_subpid[sub];
...@@ -2674,8 +2676,8 @@ static int ipath_signal_procs(struct ipath_devdata *dd, int sig) ...@@ -2674,8 +2676,8 @@ static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
continue; continue;
dev_info(&dd->pcidev->dev, "sub-context " dev_info(&dd->pcidev->dev, "sub-context "
"%d:%d in use (PID %u), sending " "%d:%d in use (PID %u), sending "
"signal %d\n", i, sub, pid, sig); "signal %d\n", i, sub, pid_nr(pid), sig);
kill_proc(pid, sig, 1); kill_pid(pid, sig, 1);
any++; any++;
} }
} }
......
...@@ -555,7 +555,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport, ...@@ -555,7 +555,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
p = dd->ipath_pageshadow[porttid + tid]; p = dd->ipath_pageshadow[porttid + tid];
dd->ipath_pageshadow[porttid + tid] = NULL; dd->ipath_pageshadow[porttid + tid] = NULL;
ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
pd->port_pid, tid); pid_nr(pd->port_pid), tid);
dd->ipath_f_put_tid(dd, &tidbase[tid], dd->ipath_f_put_tid(dd, &tidbase[tid],
RCVHQ_RCV_TYPE_EXPECTED, RCVHQ_RCV_TYPE_EXPECTED,
dd->ipath_tidinvalid); dd->ipath_tidinvalid);
...@@ -1609,7 +1609,7 @@ static int try_alloc_port(struct ipath_devdata *dd, int port, ...@@ -1609,7 +1609,7 @@ static int try_alloc_port(struct ipath_devdata *dd, int port,
port); port);
pd->port_cnt = 1; pd->port_cnt = 1;
port_fp(fp) = pd; port_fp(fp) = pd;
pd->port_pid = current->pid; pd->port_pid = get_pid(task_pid(current));
strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm)); strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
ipath_stats.sps_ports++; ipath_stats.sps_ports++;
ret = 0; ret = 0;
...@@ -1793,14 +1793,15 @@ static int find_shared_port(struct file *fp, ...@@ -1793,14 +1793,15 @@ static int find_shared_port(struct file *fp,
} }
port_fp(fp) = pd; port_fp(fp) = pd;
subport_fp(fp) = pd->port_cnt++; subport_fp(fp) = pd->port_cnt++;
pd->port_subpid[subport_fp(fp)] = current->pid; pd->port_subpid[subport_fp(fp)] =
get_pid(task_pid(current));
tidcursor_fp(fp) = 0; tidcursor_fp(fp) = 0;
pd->active_slaves |= 1 << subport_fp(fp); pd->active_slaves |= 1 << subport_fp(fp);
ipath_cdbg(PROC, ipath_cdbg(PROC,
"%s[%u] %u sharing %s[%u] unit:port %u:%u\n", "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
current->comm, current->pid, current->comm, current->pid,
subport_fp(fp), subport_fp(fp),
pd->port_comm, pd->port_pid, pd->port_comm, pid_nr(pd->port_pid),
dd->ipath_unit, pd->port_port); dd->ipath_unit, pd->port_port);
ret = 1; ret = 1;
goto done; goto done;
...@@ -2066,7 +2067,8 @@ static int ipath_close(struct inode *in, struct file *fp) ...@@ -2066,7 +2067,8 @@ static int ipath_close(struct inode *in, struct file *fp)
* the slave(s) don't wait for receive data forever. * the slave(s) don't wait for receive data forever.
*/ */
pd->active_slaves &= ~(1 << fd->subport); pd->active_slaves &= ~(1 << fd->subport);
pd->port_subpid[fd->subport] = 0; put_pid(pd->port_subpid[fd->subport]);
pd->port_subpid[fd->subport] = NULL;
mutex_unlock(&ipath_mutex); mutex_unlock(&ipath_mutex);
goto bail; goto bail;
} }
...@@ -2074,7 +2076,7 @@ static int ipath_close(struct inode *in, struct file *fp) ...@@ -2074,7 +2076,7 @@ static int ipath_close(struct inode *in, struct file *fp)
if (pd->port_hdrqfull) { if (pd->port_hdrqfull) {
ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors " ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors "
"during run\n", pd->port_comm, pd->port_pid, "during run\n", pd->port_comm, pid_nr(pd->port_pid),
pd->port_hdrqfull); pd->port_hdrqfull);
pd->port_hdrqfull = 0; pd->port_hdrqfull = 0;
} }
...@@ -2134,11 +2136,12 @@ static int ipath_close(struct inode *in, struct file *fp) ...@@ -2134,11 +2136,12 @@ static int ipath_close(struct inode *in, struct file *fp)
unlock_expected_tids(pd); unlock_expected_tids(pd);
ipath_stats.sps_ports--; ipath_stats.sps_ports--;
ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
pd->port_comm, pd->port_pid, pd->port_comm, pid_nr(pd->port_pid),
dd->ipath_unit, port); dd->ipath_unit, port);
} }
pd->port_pid = 0; put_pid(pd->port_pid);
pd->port_pid = NULL;
dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */ dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */
mutex_unlock(&ipath_mutex); mutex_unlock(&ipath_mutex);
ipath_free_pddata(dd, pd); /* after releasing the mutex */ ipath_free_pddata(dd, pd); /* after releasing the mutex */
......
...@@ -159,8 +159,8 @@ struct ipath_portdata { ...@@ -159,8 +159,8 @@ struct ipath_portdata {
/* saved total number of polled urgent packets for poll edge trigger */ /* saved total number of polled urgent packets for poll edge trigger */
u32 port_urgent_poll; u32 port_urgent_poll;
/* pid of process using this port */ /* pid of process using this port */
pid_t port_pid; struct pid *port_pid;
pid_t port_subpid[INFINIPATH_MAX_SUBPORT]; struct pid *port_subpid[INFINIPATH_MAX_SUBPORT];
/* same size as task_struct .comm[] */ /* same size as task_struct .comm[] */
char port_comm[16]; char port_comm[16];
/* pkeys set by this use of this port */ /* pkeys set by this use of this port */
...@@ -483,7 +483,7 @@ struct ipath_devdata { ...@@ -483,7 +483,7 @@ struct ipath_devdata {
/* SendDMA related entries */ /* SendDMA related entries */
spinlock_t ipath_sdma_lock; spinlock_t ipath_sdma_lock;
u64 ipath_sdma_status; unsigned long ipath_sdma_status;
unsigned long ipath_sdma_abort_jiffies; unsigned long ipath_sdma_abort_jiffies;
unsigned long ipath_sdma_abort_intr_timeout; unsigned long ipath_sdma_abort_intr_timeout;
unsigned long ipath_sdma_buf_jiffies; unsigned long ipath_sdma_buf_jiffies;
...@@ -822,8 +822,8 @@ struct ipath_devdata { ...@@ -822,8 +822,8 @@ struct ipath_devdata {
#define IPATH_SDMA_DISARMED 1 #define IPATH_SDMA_DISARMED 1
#define IPATH_SDMA_DISABLED 2 #define IPATH_SDMA_DISABLED 2
#define IPATH_SDMA_LAYERBUF 3 #define IPATH_SDMA_LAYERBUF 3
#define IPATH_SDMA_RUNNING 62 #define IPATH_SDMA_RUNNING 30
#define IPATH_SDMA_SHUTDOWN 63 #define IPATH_SDMA_SHUTDOWN 31
/* bit combinations that correspond to abort states */ /* bit combinations that correspond to abort states */
#define IPATH_SDMA_ABORT_NONE 0 #define IPATH_SDMA_ABORT_NONE 0
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* /*
* Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
* *
* This software is available to you under a choice of one of two * This software is available to you under a choice of one of two
...@@ -47,14 +47,30 @@ int ipath_make_uc_req(struct ipath_qp *qp) ...@@ -47,14 +47,30 @@ int ipath_make_uc_req(struct ipath_qp *qp)
{ {
struct ipath_other_headers *ohdr; struct ipath_other_headers *ohdr;
struct ipath_swqe *wqe; struct ipath_swqe *wqe;
unsigned long flags;
u32 hwords; u32 hwords;
u32 bth0; u32 bth0;
u32 len; u32 len;
u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
int ret = 0; int ret = 0;
if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) spin_lock_irqsave(&qp->s_lock, flags);
if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) {
if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
goto bail;
/* We are in the error state, flush the work request. */
if (qp->s_last == qp->s_head)
goto bail;
/* If DMAs are in progress, we can't flush immediately. */
if (atomic_read(&qp->s_dma_busy)) {
qp->s_flags |= IPATH_S_WAIT_DMA;
goto bail;
}
wqe = get_swqe_ptr(qp, qp->s_last);
ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
goto done; goto done;
}
ohdr = &qp->s_hdr.u.oth; ohdr = &qp->s_hdr.u.oth;
if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
...@@ -69,9 +85,12 @@ int ipath_make_uc_req(struct ipath_qp *qp) ...@@ -69,9 +85,12 @@ int ipath_make_uc_req(struct ipath_qp *qp)
qp->s_wqe = NULL; qp->s_wqe = NULL;
switch (qp->s_state) { switch (qp->s_state) {
default: default:
if (!(ib_ipath_state_ops[qp->state] &
IPATH_PROCESS_NEXT_SEND_OK))
goto bail;
/* Check if send work queue is empty. */ /* Check if send work queue is empty. */
if (qp->s_cur == qp->s_head) if (qp->s_cur == qp->s_head)
goto done; goto bail;
/* /*
* Start a new request. * Start a new request.
*/ */
...@@ -134,7 +153,7 @@ int ipath_make_uc_req(struct ipath_qp *qp) ...@@ -134,7 +153,7 @@ int ipath_make_uc_req(struct ipath_qp *qp)
break; break;
default: default:
goto done; goto bail;
} }
break; break;
...@@ -194,9 +213,14 @@ int ipath_make_uc_req(struct ipath_qp *qp) ...@@ -194,9 +213,14 @@ int ipath_make_uc_req(struct ipath_qp *qp)
ipath_make_ruc_header(to_idev(qp->ibqp.device), ipath_make_ruc_header(to_idev(qp->ibqp.device),
qp, ohdr, bth0 | (qp->s_state << 24), qp, ohdr, bth0 | (qp->s_state << 24),
qp->s_next_psn++ & IPATH_PSN_MASK); qp->s_next_psn++ & IPATH_PSN_MASK);
done:
ret = 1; ret = 1;
goto unlock;
done: bail:
qp->s_flags &= ~IPATH_S_BUSY;
unlock:
spin_unlock_irqrestore(&qp->s_lock, flags);
return ret; return ret;
} }
...@@ -258,8 +282,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -258,8 +282,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
*/ */
opcode = be32_to_cpu(ohdr->bth[0]) >> 24; opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
wc.imm_data = 0; memset(&wc, 0, sizeof wc);
wc.wc_flags = 0;
/* Compare the PSN verses the expected PSN. */ /* Compare the PSN verses the expected PSN. */
if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) { if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) {
...@@ -322,8 +345,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -322,8 +345,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
case OP(SEND_ONLY): case OP(SEND_ONLY):
case OP(SEND_ONLY_WITH_IMMEDIATE): case OP(SEND_ONLY_WITH_IMMEDIATE):
send_first: send_first:
if (qp->r_reuse_sge) { if (qp->r_flags & IPATH_R_REUSE_SGE) {
qp->r_reuse_sge = 0; qp->r_flags &= ~IPATH_R_REUSE_SGE;
qp->r_sge = qp->s_rdma_read_sge; qp->r_sge = qp->s_rdma_read_sge;
} else if (!ipath_get_rwqe(qp, 0)) { } else if (!ipath_get_rwqe(qp, 0)) {
dev->n_pkt_drops++; dev->n_pkt_drops++;
...@@ -340,13 +363,13 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -340,13 +363,13 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
case OP(SEND_MIDDLE): case OP(SEND_MIDDLE):
/* Check for invalid length PMTU or posted rwqe len. */ /* Check for invalid length PMTU or posted rwqe len. */
if (unlikely(tlen != (hdrsize + pmtu + 4))) { if (unlikely(tlen != (hdrsize + pmtu + 4))) {
qp->r_reuse_sge = 1; qp->r_flags |= IPATH_R_REUSE_SGE;
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
} }
qp->r_rcv_len += pmtu; qp->r_rcv_len += pmtu;
if (unlikely(qp->r_rcv_len > qp->r_len)) { if (unlikely(qp->r_rcv_len > qp->r_len)) {
qp->r_reuse_sge = 1; qp->r_flags |= IPATH_R_REUSE_SGE;
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
} }
...@@ -372,7 +395,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -372,7 +395,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Check for invalid length. */ /* Check for invalid length. */
/* XXX LAST len should be >= 1 */ /* XXX LAST len should be >= 1 */
if (unlikely(tlen < (hdrsize + pad + 4))) { if (unlikely(tlen < (hdrsize + pad + 4))) {
qp->r_reuse_sge = 1; qp->r_flags |= IPATH_R_REUSE_SGE;
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
} }
...@@ -380,7 +403,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -380,7 +403,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
tlen -= (hdrsize + pad + 4); tlen -= (hdrsize + pad + 4);
wc.byte_len = tlen + qp->r_rcv_len; wc.byte_len = tlen + qp->r_rcv_len;
if (unlikely(wc.byte_len > qp->r_len)) { if (unlikely(wc.byte_len > qp->r_len)) {
qp->r_reuse_sge = 1; qp->r_flags |= IPATH_R_REUSE_SGE;
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
} }
...@@ -390,14 +413,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -390,14 +413,10 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
wc.wr_id = qp->r_wr_id; wc.wr_id = qp->r_wr_id;
wc.status = IB_WC_SUCCESS; wc.status = IB_WC_SUCCESS;
wc.opcode = IB_WC_RECV; wc.opcode = IB_WC_RECV;
wc.vendor_err = 0;
wc.qp = &qp->ibqp; wc.qp = &qp->ibqp;
wc.src_qp = qp->remote_qpn; wc.src_qp = qp->remote_qpn;
wc.pkey_index = 0;
wc.slid = qp->remote_ah_attr.dlid; wc.slid = qp->remote_ah_attr.dlid;
wc.sl = qp->remote_ah_attr.sl; wc.sl = qp->remote_ah_attr.sl;
wc.dlid_path_bits = 0;
wc.port_num = 0;
/* Signal completion event if the solicited bit is set. */ /* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] & (ohdr->bth[0] &
...@@ -488,8 +507,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -488,8 +507,8 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
} }
if (qp->r_reuse_sge) if (qp->r_flags & IPATH_R_REUSE_SGE)
qp->r_reuse_sge = 0; qp->r_flags &= ~IPATH_R_REUSE_SGE;
else if (!ipath_get_rwqe(qp, 1)) { else if (!ipath_get_rwqe(qp, 1)) {
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto done; goto done;
......
...@@ -65,9 +65,9 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) ...@@ -65,9 +65,9 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
u32 length; u32 length;
qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn); qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn);
if (!qp) { if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto send_comp; goto done;
} }
rsge.sg_list = NULL; rsge.sg_list = NULL;
...@@ -91,14 +91,12 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) ...@@ -91,14 +91,12 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
* present on the wire. * present on the wire.
*/ */
length = swqe->length; length = swqe->length;
memset(&wc, 0, sizeof wc);
wc.byte_len = length + sizeof(struct ib_grh); wc.byte_len = length + sizeof(struct ib_grh);
if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) {
wc.wc_flags = IB_WC_WITH_IMM; wc.wc_flags = IB_WC_WITH_IMM;
wc.imm_data = swqe->wr.ex.imm_data; wc.imm_data = swqe->wr.ex.imm_data;
} else {
wc.wc_flags = 0;
wc.imm_data = 0;
} }
/* /*
...@@ -229,7 +227,6 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) ...@@ -229,7 +227,6 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
} }
wc.status = IB_WC_SUCCESS; wc.status = IB_WC_SUCCESS;
wc.opcode = IB_WC_RECV; wc.opcode = IB_WC_RECV;
wc.vendor_err = 0;
wc.qp = &qp->ibqp; wc.qp = &qp->ibqp;
wc.src_qp = sqp->ibqp.qp_num; wc.src_qp = sqp->ibqp.qp_num;
/* XXX do we know which pkey matched? Only needed for GSI. */ /* XXX do we know which pkey matched? Only needed for GSI. */
...@@ -248,8 +245,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) ...@@ -248,8 +245,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe)
kfree(rsge.sg_list); kfree(rsge.sg_list);
if (atomic_dec_and_test(&qp->refcount)) if (atomic_dec_and_test(&qp->refcount))
wake_up(&qp->wait); wake_up(&qp->wait);
send_comp: done:;
ipath_send_complete(sqp, swqe, IB_WC_SUCCESS);
} }
/** /**
...@@ -264,6 +260,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -264,6 +260,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
struct ipath_other_headers *ohdr; struct ipath_other_headers *ohdr;
struct ib_ah_attr *ah_attr; struct ib_ah_attr *ah_attr;
struct ipath_swqe *wqe; struct ipath_swqe *wqe;
unsigned long flags;
u32 nwords; u32 nwords;
u32 extra_bytes; u32 extra_bytes;
u32 bth0; u32 bth0;
...@@ -271,13 +268,30 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -271,13 +268,30 @@ int ipath_make_ud_req(struct ipath_qp *qp)
u16 lid; u16 lid;
int ret = 0; int ret = 0;
if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))) spin_lock_irqsave(&qp->s_lock, flags);
goto bail;
if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_NEXT_SEND_OK)) {
if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
goto bail;
/* We are in the error state, flush the work request. */
if (qp->s_last == qp->s_head)
goto bail;
/* If DMAs are in progress, we can't flush immediately. */
if (atomic_read(&qp->s_dma_busy)) {
qp->s_flags |= IPATH_S_WAIT_DMA;
goto bail;
}
wqe = get_swqe_ptr(qp, qp->s_last);
ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
goto done;
}
if (qp->s_cur == qp->s_head) if (qp->s_cur == qp->s_head)
goto bail; goto bail;
wqe = get_swqe_ptr(qp, qp->s_cur); wqe = get_swqe_ptr(qp, qp->s_cur);
if (++qp->s_cur >= qp->s_size)
qp->s_cur = 0;
/* Construct the header. */ /* Construct the header. */
ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
...@@ -288,10 +302,23 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -288,10 +302,23 @@ int ipath_make_ud_req(struct ipath_qp *qp)
dev->n_unicast_xmit++; dev->n_unicast_xmit++;
} else { } else {
dev->n_unicast_xmit++; dev->n_unicast_xmit++;
lid = ah_attr->dlid & lid = ah_attr->dlid & ~((1 << dev->dd->ipath_lmc) - 1);
~((1 << dev->dd->ipath_lmc) - 1);
if (unlikely(lid == dev->dd->ipath_lid)) { if (unlikely(lid == dev->dd->ipath_lid)) {
/*
* If DMAs are in progress, we can't generate
* a completion for the loopback packet since
* it would be out of order.
* XXX Instead of waiting, we could queue a
* zero length descriptor so we get a callback.
*/
if (atomic_read(&qp->s_dma_busy)) {
qp->s_flags |= IPATH_S_WAIT_DMA;
goto bail;
}
spin_unlock_irqrestore(&qp->s_lock, flags);
ipath_ud_loopback(qp, wqe); ipath_ud_loopback(qp, wqe);
spin_lock_irqsave(&qp->s_lock, flags);
ipath_send_complete(qp, wqe, IB_WC_SUCCESS);
goto done; goto done;
} }
} }
...@@ -368,11 +395,13 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -368,11 +395,13 @@ int ipath_make_ud_req(struct ipath_qp *qp)
ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num);
done: done:
if (++qp->s_cur >= qp->s_size)
qp->s_cur = 0;
ret = 1; ret = 1;
goto unlock;
bail: bail:
qp->s_flags &= ~IPATH_S_BUSY;
unlock:
spin_unlock_irqrestore(&qp->s_lock, flags);
return ret; return ret;
} }
...@@ -506,8 +535,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -506,8 +535,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* /*
* Get the next work request entry to find where to put the data. * Get the next work request entry to find where to put the data.
*/ */
if (qp->r_reuse_sge) if (qp->r_flags & IPATH_R_REUSE_SGE)
qp->r_reuse_sge = 0; qp->r_flags &= ~IPATH_R_REUSE_SGE;
else if (!ipath_get_rwqe(qp, 0)) { else if (!ipath_get_rwqe(qp, 0)) {
/* /*
* Count VL15 packets dropped due to no receive buffer. * Count VL15 packets dropped due to no receive buffer.
...@@ -523,7 +552,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -523,7 +552,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
} }
/* Silently drop packets which are too big. */ /* Silently drop packets which are too big. */
if (wc.byte_len > qp->r_len) { if (wc.byte_len > qp->r_len) {
qp->r_reuse_sge = 1; qp->r_flags |= IPATH_R_REUSE_SGE;
dev->n_pkt_drops++; dev->n_pkt_drops++;
goto bail; goto bail;
} }
...@@ -535,7 +564,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -535,7 +564,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh)); ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh));
ipath_copy_sge(&qp->r_sge, data, ipath_copy_sge(&qp->r_sge, data,
wc.byte_len - sizeof(struct ib_grh)); wc.byte_len - sizeof(struct ib_grh));
qp->r_wrid_valid = 0; if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
goto bail;
wc.wr_id = qp->r_wr_id; wc.wr_id = qp->r_wr_id;
wc.status = IB_WC_SUCCESS; wc.status = IB_WC_SUCCESS;
wc.opcode = IB_WC_RECV; wc.opcode = IB_WC_RECV;
......
...@@ -45,8 +45,6 @@ int ipath_user_sdma_writev(struct ipath_devdata *dd, ...@@ -45,8 +45,6 @@ int ipath_user_sdma_writev(struct ipath_devdata *dd,
int ipath_user_sdma_make_progress(struct ipath_devdata *dd, int ipath_user_sdma_make_progress(struct ipath_devdata *dd,
struct ipath_user_sdma_queue *pq); struct ipath_user_sdma_queue *pq);
int ipath_user_sdma_pkt_sent(const struct ipath_user_sdma_queue *pq,
u32 counter);
void ipath_user_sdma_queue_drain(struct ipath_devdata *dd, void ipath_user_sdma_queue_drain(struct ipath_devdata *dd,
struct ipath_user_sdma_queue *pq); struct ipath_user_sdma_queue *pq);
......
This diff is collapsed.
...@@ -74,6 +74,11 @@ ...@@ -74,6 +74,11 @@
#define IPATH_POST_RECV_OK 0x02 #define IPATH_POST_RECV_OK 0x02
#define IPATH_PROCESS_RECV_OK 0x04 #define IPATH_PROCESS_RECV_OK 0x04
#define IPATH_PROCESS_SEND_OK 0x08 #define IPATH_PROCESS_SEND_OK 0x08
#define IPATH_PROCESS_NEXT_SEND_OK 0x10
#define IPATH_FLUSH_SEND 0x20
#define IPATH_FLUSH_RECV 0x40
#define IPATH_PROCESS_OR_FLUSH_SEND \
(IPATH_PROCESS_SEND_OK | IPATH_FLUSH_SEND)
/* IB Performance Manager status values */ /* IB Performance Manager status values */
#define IB_PMA_SAMPLE_STATUS_DONE 0x00 #define IB_PMA_SAMPLE_STATUS_DONE 0x00
...@@ -353,12 +358,14 @@ struct ipath_qp { ...@@ -353,12 +358,14 @@ struct ipath_qp {
struct ib_qp ibqp; struct ib_qp ibqp;
struct ipath_qp *next; /* link list for QPN hash table */ struct ipath_qp *next; /* link list for QPN hash table */
struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */ struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */
struct ipath_qp *pio_next; /* link for ipath_ib_piobufavail() */
struct list_head piowait; /* link for wait PIO buf */ struct list_head piowait; /* link for wait PIO buf */
struct list_head timerwait; /* link for waiting for timeouts */ struct list_head timerwait; /* link for waiting for timeouts */
struct ib_ah_attr remote_ah_attr; struct ib_ah_attr remote_ah_attr;
struct ipath_ib_header s_hdr; /* next packet header to send */ struct ipath_ib_header s_hdr; /* next packet header to send */
atomic_t refcount; atomic_t refcount;
wait_queue_head_t wait; wait_queue_head_t wait;
wait_queue_head_t wait_dma;
struct tasklet_struct s_task; struct tasklet_struct s_task;
struct ipath_mmap_info *ip; struct ipath_mmap_info *ip;
struct ipath_sge_state *s_cur_sge; struct ipath_sge_state *s_cur_sge;
...@@ -369,7 +376,7 @@ struct ipath_qp { ...@@ -369,7 +376,7 @@ struct ipath_qp {
struct ipath_sge_state s_rdma_read_sge; struct ipath_sge_state s_rdma_read_sge;
struct ipath_sge_state r_sge; /* current receive data */ struct ipath_sge_state r_sge; /* current receive data */
spinlock_t s_lock; spinlock_t s_lock;
unsigned long s_busy; atomic_t s_dma_busy;
u16 s_pkt_delay; u16 s_pkt_delay;
u16 s_hdrwords; /* size of s_hdr in 32 bit words */ u16 s_hdrwords; /* size of s_hdr in 32 bit words */
u32 s_cur_size; /* size of send packet in bytes */ u32 s_cur_size; /* size of send packet in bytes */
...@@ -383,6 +390,7 @@ struct ipath_qp { ...@@ -383,6 +390,7 @@ struct ipath_qp {
u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */
u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ u32 r_ack_psn; /* PSN for next ACK or atomic ACK */
u64 r_wr_id; /* ID for current receive WQE */ u64 r_wr_id; /* ID for current receive WQE */
unsigned long r_aflags;
u32 r_len; /* total length of r_sge */ u32 r_len; /* total length of r_sge */
u32 r_rcv_len; /* receive data len processed */ u32 r_rcv_len; /* receive data len processed */
u32 r_psn; /* expected rcv packet sequence number */ u32 r_psn; /* expected rcv packet sequence number */
...@@ -394,8 +402,7 @@ struct ipath_qp { ...@@ -394,8 +402,7 @@ struct ipath_qp {
u8 r_state; /* opcode of last packet received */ u8 r_state; /* opcode of last packet received */
u8 r_nak_state; /* non-zero if NAK is pending */ u8 r_nak_state; /* non-zero if NAK is pending */
u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */
u8 r_reuse_sge; /* for UC receive errors */ u8 r_flags;
u8 r_wrid_valid; /* r_wrid set but CQ entry not yet made */
u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */
u8 r_head_ack_queue; /* index into s_ack_queue[] */ u8 r_head_ack_queue; /* index into s_ack_queue[] */
u8 qp_access_flags; u8 qp_access_flags;
...@@ -404,13 +411,13 @@ struct ipath_qp { ...@@ -404,13 +411,13 @@ struct ipath_qp {
u8 s_rnr_retry_cnt; u8 s_rnr_retry_cnt;
u8 s_retry; /* requester retry counter */ u8 s_retry; /* requester retry counter */
u8 s_rnr_retry; /* requester RNR retry counter */ u8 s_rnr_retry; /* requester RNR retry counter */
u8 s_wait_credit; /* limit number of unacked packets sent */
u8 s_pkey_index; /* PKEY index to use */ u8 s_pkey_index; /* PKEY index to use */
u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */
u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */
u8 s_tail_ack_queue; /* index into s_ack_queue[] */ u8 s_tail_ack_queue; /* index into s_ack_queue[] */
u8 s_flags; u8 s_flags;
u8 s_dmult; u8 s_dmult;
u8 s_draining;
u8 timeout; /* Timeout for this QP */ u8 timeout; /* Timeout for this QP */
enum ib_mtu path_mtu; enum ib_mtu path_mtu;
u32 remote_qpn; u32 remote_qpn;
...@@ -428,16 +435,40 @@ struct ipath_qp { ...@@ -428,16 +435,40 @@ struct ipath_qp {
struct ipath_sge r_sg_list[0]; /* verified SGEs */ struct ipath_sge r_sg_list[0]; /* verified SGEs */
}; };
/* Bit definition for s_busy. */ /*
#define IPATH_S_BUSY 0 * Atomic bit definitions for r_aflags.
*/
#define IPATH_R_WRID_VALID 0
/*
* Bit definitions for r_flags.
*/
#define IPATH_R_REUSE_SGE 0x01
#define IPATH_R_RDMAR_SEQ 0x02
/* /*
* Bit definitions for s_flags. * Bit definitions for s_flags.
*
* IPATH_S_FENCE_PENDING - waiting for all prior RDMA read or atomic SWQEs
* before processing the next SWQE
* IPATH_S_RDMAR_PENDING - waiting for any RDMA read or atomic SWQEs
* before processing the next SWQE
* IPATH_S_WAITING - waiting for RNR timeout or send buffer available.
* IPATH_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE
* IPATH_S_WAIT_DMA - waiting for send DMA queue to drain before generating
* next send completion entry not via send DMA.
*/ */
#define IPATH_S_SIGNAL_REQ_WR 0x01 #define IPATH_S_SIGNAL_REQ_WR 0x01
#define IPATH_S_FENCE_PENDING 0x02 #define IPATH_S_FENCE_PENDING 0x02
#define IPATH_S_RDMAR_PENDING 0x04 #define IPATH_S_RDMAR_PENDING 0x04
#define IPATH_S_ACK_PENDING 0x08 #define IPATH_S_ACK_PENDING 0x08
#define IPATH_S_BUSY 0x10
#define IPATH_S_WAITING 0x20
#define IPATH_S_WAIT_SSN_CREDIT 0x40
#define IPATH_S_WAIT_DMA 0x80
#define IPATH_S_ANY_WAIT (IPATH_S_FENCE_PENDING | IPATH_S_RDMAR_PENDING | \
IPATH_S_WAITING | IPATH_S_WAIT_SSN_CREDIT | IPATH_S_WAIT_DMA)
#define IPATH_PSN_CREDIT 512 #define IPATH_PSN_CREDIT 512
...@@ -573,13 +604,11 @@ struct ipath_ibdev { ...@@ -573,13 +604,11 @@ struct ipath_ibdev {
u32 n_rnr_naks; u32 n_rnr_naks;
u32 n_other_naks; u32 n_other_naks;
u32 n_timeouts; u32 n_timeouts;
u32 n_rc_stalls;
u32 n_pkt_drops; u32 n_pkt_drops;
u32 n_vl15_dropped; u32 n_vl15_dropped;
u32 n_wqe_errs; u32 n_wqe_errs;
u32 n_rdma_dup_busy; u32 n_rdma_dup_busy;
u32 n_piowait; u32 n_piowait;
u32 n_no_piobuf;
u32 n_unaligned; u32 n_unaligned;
u32 port_cap_flags; u32 port_cap_flags;
u32 pma_sample_start; u32 pma_sample_start;
...@@ -657,6 +686,17 @@ static inline struct ipath_ibdev *to_idev(struct ib_device *ibdev) ...@@ -657,6 +686,17 @@ static inline struct ipath_ibdev *to_idev(struct ib_device *ibdev)
return container_of(ibdev, struct ipath_ibdev, ibdev); return container_of(ibdev, struct ipath_ibdev, ibdev);
} }
/*
* This must be called with s_lock held.
*/
static inline void ipath_schedule_send(struct ipath_qp *qp)
{
if (qp->s_flags & IPATH_S_ANY_WAIT)
qp->s_flags &= ~IPATH_S_ANY_WAIT;
if (!(qp->s_flags & IPATH_S_BUSY))
tasklet_hi_schedule(&qp->s_task);
}
int ipath_process_mad(struct ib_device *ibdev, int ipath_process_mad(struct ib_device *ibdev,
int mad_flags, int mad_flags,
u8 port_num, u8 port_num,
...@@ -706,12 +746,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, ...@@ -706,12 +746,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int attr_mask, struct ib_qp_init_attr *init_attr); int attr_mask, struct ib_qp_init_attr *init_attr);
void ipath_free_all_qps(struct ipath_qp_table *qpt); unsigned ipath_free_all_qps(struct ipath_qp_table *qpt);
int ipath_init_qp_table(struct ipath_ibdev *idev, int size); int ipath_init_qp_table(struct ipath_ibdev *idev, int size);
void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
void ipath_get_credit(struct ipath_qp *qp, u32 aeth); void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
unsigned ipath_ib_rate_to_mult(enum ib_rate rate); unsigned ipath_ib_rate_to_mult(enum ib_rate rate);
...@@ -729,7 +767,9 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -729,7 +767,9 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int has_grh, void *data, u32 tlen, struct ipath_qp *qp); int has_grh, void *data, u32 tlen, struct ipath_qp *qp);
void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc); void ipath_restart_rc(struct ipath_qp *qp, u32 psn);
void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err);
int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr); int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr);
......
...@@ -91,10 +91,6 @@ unsigned int nes_debug_level = 0; ...@@ -91,10 +91,6 @@ unsigned int nes_debug_level = 0;
module_param_named(debug_level, nes_debug_level, uint, 0644); module_param_named(debug_level, nes_debug_level, uint, 0644);
MODULE_PARM_DESC(debug_level, "Enable debug output level"); MODULE_PARM_DESC(debug_level, "Enable debug output level");
unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR);
MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation");
LIST_HEAD(nes_adapter_list); LIST_HEAD(nes_adapter_list);
static LIST_HEAD(nes_dev_list); static LIST_HEAD(nes_dev_list);
......
...@@ -173,7 +173,6 @@ extern int disable_mpa_crc; ...@@ -173,7 +173,6 @@ extern int disable_mpa_crc;
extern unsigned int send_first; extern unsigned int send_first;
extern unsigned int nes_drv_opt; extern unsigned int nes_drv_opt;
extern unsigned int nes_debug_level; extern unsigned int nes_debug_level;
extern unsigned int nes_lro_max_aggr;
extern struct list_head nes_adapter_list; extern struct list_head nes_adapter_list;
......
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
#include "nes.h" #include "nes.h"
static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
module_param(nes_lro_max_aggr, uint, 0444);
MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
static u32 crit_err_count; static u32 crit_err_count;
u32 int_mod_timer_init; u32 int_mod_timer_init;
u32 int_mod_cq_depth_256; u32 int_mod_cq_depth_256;
...@@ -1738,7 +1742,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) ...@@ -1738,7 +1742,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
jumbomode = 1; jumbomode = 1;
nes_nic_init_timer_defaults(nesdev, jumbomode); nes_nic_init_timer_defaults(nesdev, jumbomode);
} }
nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR; nesvnic->lro_mgr.max_aggr = nes_lro_max_aggr;
nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS; nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS;
nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc; nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc;
nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr; nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
......
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