PERFORCE change 128501 for review
Kip Macy
kmacy at FreeBSD.org
Thu Nov 1 22:03:43 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=128501
Change 128501 by kmacy at kmacy:storage:toestack on 2007/11/02 05:03:39
add core functionality for transmit - but don't yet
hook in to cxgb_toe_send
Affected files ...
.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#10 edit
.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#2 edit
.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.h#2 edit
Differences ...
==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#10 (text+ko) ====
@@ -108,7 +108,7 @@
* in the skb and whether it has any payload in its main body. This maps the
* length of the gather list represented by an skb into the # of necessary WRs.
*/
-static unsigned int skb_wrs[MAX_PAGE_IOV + 2] __read_mostly;
+static unsigned int mbuf_wrs[TX_MAX_SEGS] __read_mostly;
/*
* Max receive window supported by HW in bytes. Only a small part of it can
@@ -122,6 +122,133 @@
*/
#define MIN_RCV_WND (24 * 1024U)
+
+extern int tcp_do_autorcvbuf;
+extern int tcp_do_autosndbuf;
+extern int tcp_autorcvbuf_max;
+extern int tcp_autosndbuf_max;
+
+static inline unsigned int
+mkprio(unsigned int cntrl, const struct socket *so)
+{
+ return cntrl;
+}
+
+
+static inline void
+make_tx_data_wr(struct socket *so, struct mbuf *m, int len, struct mbuf *tail)
+{
+ struct tcpcb *tp = sototcpcb(so);
+ struct toepcb *toep = tp->t_toe;
+ struct tx_data_wr *req;
+
+ req = mtod(m, struct tx_data_wr *);
+ m->m_len = sizeof(*req);
+ req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
+ req->wr_lo = htonl(V_WR_TID(toep->tp_tid));
+ req->sndseq = htonl(tp->snd_nxt);
+ /* len includes the length of any HW ULP additions */
+ req->len = htonl(len);
+ req->param = htonl(V_TX_PORT(toep->tp_l2t->smt_idx));
+ /* V_TX_ULP_SUBMODE sets both the mode and submode */
+ req->flags = htonl(V_TX_ULP_SUBMODE(/*skb_ulp_mode(skb)*/ 0) |
+ V_TX_URG(/* skb_urgent(skb) */ 0 ) |
+ V_TX_SHOVE((!(tp->t_flags & TF_MORETOCOME) &&
+ (tail ? 0 : 1))));
+
+ if (__predict_false((toep->tp_flags & TP_DATASENT) == 0)) {
+ req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT |
+ V_TX_CPU_IDX(toep->tp_qset_idx));
+
+ /* Sendbuffer is in units of 32KB.
+ */
+ if (tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE)
+ req->param |= htonl(V_TX_SNDBUF(tcp_autosndbuf_max >> 15));
+ else
+ req->param |= htonl(V_TX_SNDBUF(so->so_snd.sb_hiwat >> 15));
+ toep->tp_flags |= TP_DATASENT;
+ }
+
+
+
+}
+
+int
+t3_push_frames(struct socket *so, int req_completion)
+{
+ struct tcpcb *tp = sototcpcb(so);
+ struct toepcb *toep = tp->t_toe;
+
+ struct mbuf *tail, *m0;
+ struct t3cdev *cdev;
+ struct tom_data *d;
+ int bytes, count, total_bytes;
+ bus_dma_segment_t segs[TX_MAX_SEGS], *segp;
+ segp = segs;
+
+ if (tp->t_state == TCPS_SYN_SENT || tp->t_state == TCPS_CLOSED)
+ return (0);
+
+ if (so->so_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED))
+ return (0);
+
+ d = TOM_DATA(TOE_DEV(so));
+ cdev = d->cdev;
+ tail = so->so_snd.sb_sndptr ? so->so_snd.sb_sndptr : so->so_snd.sb_mb;
+ total_bytes = 0;
+
+ while (toep->tp_wr_avail && (tail != NULL)) {
+
+ count = bytes = 0;
+ if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
+ return (0);
+
+ while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail) && (tail != NULL) && (count < TX_MAX_SEGS)) {
+ bytes += tail->m_len;
+ count++;
+
+ /*
+ * technically an abuse to be using this for a VA
+ * but less gross than defining my own structure
+ * or calling pmap_kextract from here :-|
+ */
+ segp->ds_addr = (bus_addr_t)tail->m_data;
+ segp->ds_len = tail->m_len;
+ segp++;
+ tail = tail->m_next;
+ }
+
+ so->so_snd.sb_sndptr = tail;
+ so->so_snd.sb_sndptroff += bytes;
+ total_bytes += bytes;
+
+
+ /*
+ * XXX can drop socket buffer lock here
+ */
+
+ toep->tp_wr_avail -= mbuf_wrs[count];
+ toep->tp_wr_unacked += mbuf_wrs[count];
+
+ make_tx_data_wr(so, m0, bytes, tail);
+ m_set_priority(m0, mkprio(CPL_PRIORITY_DATA, so));
+ m_set_sgl(m0, segs);
+ m_set_sgllen(m0, count);
+ m0->m_pkthdr.len = bytes;
+ if ((req_completion && toep->tp_wr_unacked == mbuf_wrs[count]) ||
+ toep->tp_wr_unacked >= toep->tp_wr_max / 2) {
+ struct work_request_hdr *wr = cplhdr(m0);
+
+ wr->wr_hi |= htonl(F_WR_COMPL);
+ toep->tp_wr_unacked = 0;
+ }
+
+ l2t_send(cdev, m0, toep->tp_l2t);
+ }
+
+ return (total_bytes);
+}
+
static int
cxgb_toe_disconnect(struct tcpcb *tp)
{
@@ -188,12 +315,6 @@
cxgb_insert_tid(d->cdev, d->client, so, tid);
}
-static inline unsigned int
-mkprio(unsigned int cntrl, const struct socket *so)
-{
- return cntrl;
-}
-
/**
* find_best_mtu - find the entry in the MTU table closest to an MTU
* @d: TOM state
@@ -247,9 +368,6 @@
tp->t_tu = &cxgb_toe_usrreqs;
}
-extern int tcp_do_autorcvbuf;
-extern int tcp_autorcvbuf_max;
-
/*
* Determine the receive window scaling factor given a target max
* receive window.
@@ -684,14 +802,14 @@
{
int i;
- if (skb_wrs[1]) /* already initialized */
+ if (mbuf_wrs[1]) /* already initialized */
return;
- for (i = 1; i < ARRAY_SIZE(skb_wrs); i++) {
+ for (i = 1; i < ARRAY_SIZE(mbuf_wrs); i++) {
int sgl_len = (3 * i) / 2 + (i & 1);
sgl_len += 3;
- skb_wrs[i] = sgl_len <= wr_len ?
+ mbuf_wrs[i] = sgl_len <= wr_len ?
1 : 1 + (sgl_len - 2) / (wr_len - 1);
}
==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#2 (text+ko) ====
@@ -13,6 +13,8 @@
void t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h);
void t3_init_offload_ops(void);
void t3_init_wr_tab(unsigned int wr_len);
+int t3_push_frames(struct socket *so, int req_completion);
+
void toepcb_hold(struct toepcb *);
void toepcb_release(struct toepcb *);
void toepcb_init(struct toepcb *);
==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.h#2 (text+ko) ====
@@ -78,6 +78,8 @@
#define T3C_DEV(sk) ((TOM_DATA(TOE_DEV(sk)))->cdev)
#define TOM_TUNABLE(dev, param) (TOM_DATA(dev)->conf.param)
+#define TP_DATASENT (1 << 0)
+
struct toepcb {
struct toedev *tp_toedev;
int tp_tid;
@@ -91,6 +93,8 @@
int tp_qset_idx;
int tp_mss_clamp;
int tp_qset;
+ int tp_flags;
+
volatile int tp_refcount;
struct tcpcb *tp_tp;
More information about the p4-projects
mailing list