* [PATCH 2/4] libcxgbi: pdu read fixes
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q
[PATCH 2/4] libcxgbi: pdu read fixes
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
This patch
- fixed the locking and releasing skb in the case of error in the pdu read path, and
- added define iscsi_task_cxgbi_data to access the private data inside the iscsi_task.
Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---
drivers/scsi/cxgbi/libcxgbi.c | 79 ++++++++++++++++++++++++++---------------
drivers/scsi/cxgbi/libcxgbi.h | 2 +
2 files changed, 53 insertions(+), 28 deletions(-)
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index db9d08a..7136fb2 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -593,11 +593,11 @@ static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
csk, csk->state, csk->flags, csk->user_data);
if (csk->state != CTP_ESTABLISHED) {
- read_lock(&csk->callback_lock);
+ read_lock_bh(&csk->callback_lock);
if (csk->user_data)
iscsi_conn_failure(csk->user_data,
ISCSI_ERR_CONN_FAILED);
- read_unlock(&csk->callback_lock);
+ read_unlock_bh(&csk->callback_lock);
}
}
@@ -1712,12 +1712,10 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
"csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
csk, conn, conn ? conn->id : 0xFF,
conn ? conn->suspend_rx : 0xFF);
- read_unlock(&csk->callback_lock);
return;
}
while (!err) {
- read_lock(&csk->callback_lock);
skb = skb_peek(&csk->receive_queue);
if (!skb ||
!(cxgbi_skcb_test_flag(skb, SKCBF_RX_STATUS))) {
@@ -1725,11 +1723,9 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
log_debug(1 << CXGBI_DBG_PDU_RX,
"skb 0x%p, NOT ready 0x%lx.\n",
skb, cxgbi_skcb_flags(skb));
- read_unlock(&csk->callback_lock);
break;
}
__skb_unlink(skb, &csk->receive_queue);
- read_unlock(&csk->callback_lock);
read += cxgbi_skcb_rx_pdulen(skb);
log_debug(1 << CXGBI_DBG_PDU_RX,
@@ -1739,37 +1735,66 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) {
err = skb_read_pdu_bhs(conn, skb);
- if (err < 0)
- break;
+ if (err < 0) {
+ pr_err("coalesced bhs, csk 0x%p, skb 0x%p,%u, "
+ "f 0x%lx, plen %u.\n",
+ csk, skb, skb->len,
+ cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb));
+ goto skb_done;
+ }
err = skb_read_pdu_data(conn, skb, skb,
err + cdev->skb_rx_extra);
+ if (err < 0)
+ pr_err("coalesced data, csk 0x%p, skb 0x%p,%u, "
+ "f 0x%lx, plen %u.\n",
+ csk, skb, skb->len,
+ cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb));
} else {
err = skb_read_pdu_bhs(conn, skb);
- if (err < 0)
- break;
+ if (err < 0) {
+ pr_err("bhs, csk 0x%p, skb 0x%p,%u, "
+ "f 0x%lx, plen %u.\n",
+ csk, skb, skb->len,
+ cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb));
+ goto skb_done;
+ }
+
if (cxgbi_skcb_test_flag(skb, SKCBF_RX_DATA)) {
struct sk_buff *dskb;
- read_lock(&csk->callback_lock);
dskb = skb_peek(&csk->receive_queue);
if (!dskb) {
- read_unlock(&csk->callback_lock);
- pr_err("csk 0x%p, NO data.\n", csk);
- err = -EAGAIN;
- break;
+ pr_err("csk 0x%p, skb 0x%p,%u, f 0x%lx,"
+ " plen %u, NO data.\n",
+ csk, skb, skb->len,
+ cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb));
+ err = -EIO;
+ goto skb_done;
}
__skb_unlink(dskb, &csk->receive_queue);
- read_unlock(&csk->callback_lock);
err = skb_read_pdu_data(conn, skb, dskb, 0);
+ if (err < 0)
+ pr_err("data, csk 0x%p, skb 0x%p,%u, "
+ "f 0x%lx, plen %u, dskb 0x%p,"
+ "%u.\n",
+ csk, skb, skb->len,
+ cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb),
+ dskb, dskb->len);
__kfree_skb(dskb);
} else
err = skb_read_pdu_data(conn, skb, skb, 0);
}
+skb_done:
+ __kfree_skb(skb);
+
if (err < 0)
break;
-
- __kfree_skb(skb);
}
log_debug(1 << CXGBI_DBG_PDU_RX, "csk 0x%p, read %u.\n", csk, read);
@@ -1780,7 +1805,8 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
}
if (err < 0) {
- pr_info("csk 0x%p, 0x%p, rx failed %d.\n", csk, conn, err);
+ pr_info("csk 0x%p, 0x%p, rx failed %d, read %u.\n",
+ csk, conn, err, read);
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
}
}
@@ -1861,7 +1887,7 @@ int cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
struct cxgbi_device *cdev = cconn->chba->cdev;
struct iscsi_conn *conn = task->conn;
struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct cxgbi_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+ struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
struct scsi_cmnd *sc = task->sc;
int headroom = SKB_TX_ISCSI_PDU_HEADER_MAX;
@@ -1916,8 +1942,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
unsigned int count)
{
struct iscsi_conn *conn = task->conn;
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct cxgbi_task_data *tdata = tcp_task->dd_data;
+ struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
struct sk_buff *skb = tdata->skb;
unsigned int datalen = count;
int i, padlen = iscsi_padding(count);
@@ -2019,8 +2044,7 @@ int cxgbi_conn_xmit_pdu(struct iscsi_task *task)
{
struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
struct cxgbi_conn *cconn = tcp_conn->dd_data;
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct cxgbi_task_data *tdata = tcp_task->dd_data;
+ struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
struct sk_buff *skb = tdata->skb;
unsigned int datalen;
int err;
@@ -2072,8 +2096,7 @@ EXPORT_SYMBOL_GPL(cxgbi_conn_xmit_pdu);
void cxgbi_cleanup_task(struct iscsi_task *task)
{
- struct cxgbi_task_data *tdata = task->dd_data +
- sizeof(struct iscsi_tcp_task);
+ struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
log_debug(1 << CXGBI_DBG_ISCSI,
"task 0x%p, skb 0x%p, itt 0x%x.\n",
@@ -2290,12 +2313,12 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
/* calculate the tag idx bits needed for this conn based on cmds_max */
cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
- write_lock(&csk->callback_lock);
+ write_lock_bh(&csk->callback_lock);
csk->user_data = conn;
cconn->chba = cep->chba;
cconn->cep = cep;
cep->cconn = cconn;
- write_unlock(&csk->callback_lock);
+ write_unlock_bh(&csk->callback_lock);
cxgbi_conn_max_xmit_dlength(conn);
cxgbi_conn_max_recv_dlength(conn);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 2f2485b..48e6d62 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -592,6 +592,8 @@ struct cxgbi_task_data {
unsigned int count;
unsigned int sgoffset;
};
+#define iscsi_task_cxgbi_data(task) \
+ ((task)->dd_data + sizeof(struct iscsi_tcp_task))
static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag)
{
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.
^ permalink raw reply related
* [PATCH 4/4] cxgb4i: connection and ddp setting update
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q
[PATCH 4/4] cxgb4i: connection and ddp setting update
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
This patch updated cxgb4i connection setting and pagepod programming.
Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 128 +++++++++++++++++++-----------------
drivers/scsi/cxgbi/cxgb4i/cxgb4i.h | 5 +
drivers/scsi/cxgbi/libcxgbi.h | 10 ---
3 files changed, 71 insertions(+), 72 deletions(-)
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 1056d97..99f2b8c 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -34,8 +34,8 @@ static unsigned int dbg_level;
#define DRV_MODULE_NAME "cxgb4i"
#define DRV_MODULE_DESC "Chelsio T4 iSCSI Driver"
-#define DRV_MODULE_VERSION "0.9.0"
-#define DRV_MODULE_RELDATE "May 2010"
+#define DRV_MODULE_VERSION "0.9.1"
+#define DRV_MODULE_RELDATE "Aug. 2010"
static char version[] =
DRV_MODULE_DESC " " DRV_MODULE_NAME
@@ -396,7 +396,7 @@ static inline void send_tx_flowc_wr(struct cxgbi_sock *csk)
htonl(FW_WR_LEN16(DIV_ROUND_UP(72, 16)) |
FW_WR_FLOWID(csk->tid));
flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
- flowc->mnemval[0].val = htonl(0);
+ flowc->mnemval[0].val = htonl(csk->cdev->pfvf);
flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
flowc->mnemval[1].val = htonl(csk->tx_chan);
flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
@@ -568,6 +568,12 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
goto rel_skb;
}
+ if (csk->atid != atid) {
+ pr_err("bad conn atid %u, csk 0x%p,%u,0x%lx,tid %u, atid %u.\n",
+ atid, csk, csk->state, csk->flags, csk->tid, csk->atid);
+ goto rel_skb;
+ }
+
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p,%u,0x%lx, tid %u, atid %u, rseq %u.\n",
csk, csk->state, csk->flags, tid, atid, rcv_isn);
@@ -681,9 +687,10 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
goto rel_skb;
}
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,%u,0x%lx, status %u, atid %u, tid %u.\n",
- csk, csk->state, csk->flags, status, atid, tid);
+ pr_info("%pI4:%u-%pI4:%u, atid %u,%u, status %u, csk 0x%p,%u,0x%lx.\n",
+ &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port),
+ &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port),
+ atid, tid, status, csk, csk->state, csk->flags);
if (status && status != CPL_ERR_TCAM_FULL &&
status != CPL_ERR_CONN_EXIST &&
@@ -846,7 +853,6 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
unsigned int tid = GET_TID(cpl);
struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
struct tid_info *t = lldi->tids;
- struct sk_buff *lskb;
csk = lookup_tid(t, tid);
if (unlikely(!csk)) {
@@ -872,6 +878,8 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
}
cxgbi_skcb_tcp_seq(skb) = ntohl(cpl->seq);
+ cxgbi_skcb_flags(skb) = 0;
+
skb_reset_transport_header(skb);
__skb_pull(skb, sizeof(*cpl));
__pskb_trim(skb, ntohs(cpl->len));
@@ -884,17 +892,16 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
"csk 0x%p,%u,0x%lx, tid %u, skb 0x%p header.\n",
csk, csk->state, csk->flags, csk->tid, skb);
csk->skb_ulp_lhdr = skb;
- lskb = csk->skb_ulp_lhdr;
- cxgbi_skcb_set_flag(lskb, SKCBF_RX_HDR);
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_HDR);
- if (cxgbi_skcb_tcp_seq(lskb) != csk->rcv_nxt) {
+ if (cxgbi_skcb_tcp_seq(skb) != csk->rcv_nxt) {
pr_info("tid %u, CPL_ISCSI_HDR, bad seq, 0x%x/0x%x.\n",
- csk->tid, cxgbi_skcb_tcp_seq(lskb),
+ csk->tid, cxgbi_skcb_tcp_seq(skb),
csk->rcv_nxt);
goto abort_conn;
}
- bhs = lskb->data;
+ bhs = skb->data;
hlen = ntohs(cpl->len);
dlen = ntohl(*(unsigned int *)(bhs + 4)) & 0xFFFFFF;
@@ -918,9 +925,9 @@ static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
ntohl(*((unsigned int *)(bhs + 24))));
} else {
- lskb = csk->skb_ulp_lhdr;
- cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA);
+ struct sk_buff *lskb = csk->skb_ulp_lhdr;
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA);
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
"csk 0x%p,%u,0x%lx, skb 0x%p data, 0x%p.\n",
csk, csk->state, csk->flags, skb, lskb);
@@ -979,7 +986,6 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
lskb = csk->skb_ulp_lhdr;
csk->skb_ulp_lhdr = NULL;
- cxgbi_skcb_set_flag(lskb, SKCBF_RX_STATUS);
cxgbi_skcb_rx_ddigest(lskb) = ntohl(rpl->ulp_crc);
if (ntohs(rpl->len) != cxgbi_skcb_rx_pdulen(lskb))
@@ -987,15 +993,13 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
csk->tid, ntohs(rpl->len), cxgbi_skcb_rx_pdulen(lskb));
if (status & (1 << CPL_RX_DDP_STATUS_HCRC_SHIFT)) {
- log_debug(1 << CXGBI_DBG_PDU_RX,
- "csk 0x%p, lhdr 0x%p, status 0x%x, hcrc bad.\n",
- csk, lskb, status);
+ pr_info("csk 0x%p, lhdr 0x%p, status 0x%x, hcrc bad 0x%lx.\n",
+ csk, lskb, status, cxgbi_skcb_flags(lskb));
cxgbi_skcb_set_flag(lskb, SKCBF_RX_HCRC_ERR);
}
if (status & (1 << CPL_RX_DDP_STATUS_DCRC_SHIFT)) {
- log_debug(1 << CXGBI_DBG_PDU_RX,
- "csk 0x%p, lhdr 0x%p, status 0x%x, dcrc bad.\n",
- csk, lskb, status);
+ pr_info("csk 0x%p, lhdr 0x%p, status 0x%x, dcrc bad 0x%lx.\n",
+ csk, lskb, status, cxgbi_skcb_flags(lskb));
cxgbi_skcb_set_flag(lskb, SKCBF_RX_DCRC_ERR);
}
if (status & (1 << CPL_RX_DDP_STATUS_PAD_SHIFT)) {
@@ -1015,6 +1019,7 @@ static void do_rx_data_ddp(struct cxgbi_device *cdev,
"csk 0x%p, lskb 0x%p, f 0x%lx.\n",
csk, lskb, cxgbi_skcb_flags(lskb));
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_STATUS);
cxgbi_conn_pdu_ready(csk);
spin_unlock_bh(&csk->lock);
goto rel_skb;
@@ -1234,41 +1239,41 @@ int cxgb4i_ofld_init(struct cxgbi_device *cdev)
/*
* functions to program the pagepod in h/w
*/
+#define ULPMEM_IDATA_MAX_NPPODS 4 /* 256/PPOD_SIZE */
static inline void ulp_mem_io_set_hdr(struct ulp_mem_io *req,
- unsigned int dlen, unsigned int pm_addr)
+ unsigned int wr_len, unsigned int dlen,
+ unsigned int pm_addr)
{
- struct ulptx_sgl *sgl;
- unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
- sizeof(struct ulptx_sgl), 16);
+ struct ulptx_idata *idata = (struct ulptx_idata *)(req + 1);
INIT_ULPTX_WR(req, wr_len, 0, 0);
- req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE));
+ req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1 << 23));
req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5));
req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5));
req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16));
- sgl = (struct ulptx_sgl *)(req + 1);
- sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(1));
- sgl->len0 = htonl(dlen);
+
+ idata->cmd_more = htonl(ULPTX_CMD(ULP_TX_SC_IMM));
+ idata->len = htonl(dlen);
}
-static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
+static int ddp_ppod_write_idata(struct cxgbi_device *cdev, unsigned int port_id,
struct cxgbi_pagepod_hdr *hdr, unsigned int idx,
unsigned int npods,
struct cxgbi_gather_list *gl,
unsigned int gl_pidx)
{
struct cxgbi_ddp_info *ddp = cdev->ddp;
- unsigned int dlen, pm_addr;
struct sk_buff *skb;
struct ulp_mem_io *req;
- struct ulptx_sgl *sgl;
+ struct ulptx_idata *idata;
struct cxgbi_pagepod *ppod;
+ unsigned int pm_addr = idx * PPOD_SIZE + ddp->llimit;
+ unsigned int dlen = PPOD_SIZE * npods;
+ unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
+ sizeof(struct ulptx_idata) + dlen, 16);
unsigned int i;
- dlen = PPOD_SIZE * npods;
- pm_addr = idx * PPOD_SIZE + ddp->llimit;
-
- skb = alloc_wr(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
+ skb = alloc_wr(wr_len, 0, GFP_ATOMIC);
if (!skb) {
pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
cdev, idx, npods);
@@ -1277,10 +1282,9 @@ static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
req = (struct ulp_mem_io *)skb->head;
set_queue(skb, CPL_PRIORITY_CONTROL, NULL);
- ulp_mem_io_set_hdr(req, dlen, pm_addr);
- sgl = (struct ulptx_sgl *)(req + 1);
- ppod = (struct cxgbi_pagepod *)(sgl + 1);
- sgl->addr0 = cpu_to_be64(virt_to_phys(ppod));
+ ulp_mem_io_set_hdr(req, wr_len, dlen, pm_addr);
+ idata = (struct ulptx_idata *)(req + 1);
+ ppod = (struct cxgbi_pagepod *)(idata + 1);
for (i = 0; i < npods; i++, ppod++, gl_pidx += PPOD_PAGES_MAX) {
if (!hdr && !gl)
@@ -1302,9 +1306,9 @@ static int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
for (i = 0; i < npods; i += cnt, idx += cnt) {
cnt = npods - i;
- if (cnt > ULPMEM_DSGL_MAX_NPPODS)
- cnt = ULPMEM_DSGL_MAX_NPPODS;
- err = ddp_ppod_write_sgl(csk->cdev, csk->port_id, hdr,
+ if (cnt > ULPMEM_IDATA_MAX_NPPODS)
+ cnt = ULPMEM_IDATA_MAX_NPPODS;
+ err = ddp_ppod_write_idata(csk->cdev, csk->port_id, hdr,
idx, cnt, gl, 4 * i);
if (err < 0)
break;
@@ -1320,9 +1324,9 @@ static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
for (i = 0; i < npods; i += cnt, idx += cnt) {
cnt = npods - i;
- if (cnt > ULPMEM_DSGL_MAX_NPPODS)
- cnt = ULPMEM_DSGL_MAX_NPPODS;
- err = ddp_ppod_write_sgl(chba->cdev, chba->port_id, NULL,
+ if (cnt > ULPMEM_IDATA_MAX_NPPODS)
+ cnt = ULPMEM_IDATA_MAX_NPPODS;
+ err = ddp_ppod_write_idata(chba->cdev, chba->port_id, NULL,
idx, cnt, NULL, 0);
if (err < 0)
break;
@@ -1334,26 +1338,22 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
{
struct sk_buff *skb;
struct cpl_set_tcb_field *req;
- u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
- if (!pg_idx)
+ if (!pg_idx || pg_idx >= DDP_PGIDX_MAX)
return 0;
skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
if (!skb)
return -ENOMEM;
- /* set up ulp submode and page size */
- val = (val & 0x03) << 2;
- val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
-
+ /* set up ulp page size */
req = (struct cpl_set_tcb_field *)skb->head;
INIT_TP_WR(req, csk->tid);
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, csk->tid));
req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
- req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
- req->mask = cpu_to_be64(TCB_ULP_TYPE(TCB_ULP_TYPE_MASK));
- req->val = cpu_to_be64(val);
+ req->word_cookie = htons(0);
+ req->mask = cpu_to_be64(0x3 << 8);
+ req->val = cpu_to_be64(pg_idx << 8);
set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@@ -1368,10 +1368,9 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
{
struct sk_buff *skb;
struct cpl_set_tcb_field *req;
- u64 val = (hcrc ? ULP_CRC_HEADER : 0) | (dcrc ? ULP_CRC_DATA : 0);
- val = TCB_ULP_RAW(val);
- val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
+ if (!hcrc && !dcrc)
+ return 0;
skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
if (!skb)
@@ -1379,14 +1378,15 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
csk->hcrc_len = (hcrc ? 4 : 0);
csk->dcrc_len = (dcrc ? 4 : 0);
- /* set up ulp submode and page size */
+ /* set up ulp submode */
req = (struct cpl_set_tcb_field *)skb->head;
INIT_TP_WR(req, tid);
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
- req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
- req->mask = cpu_to_be64(TCB_ULP_RAW(TCB_ULP_RAW_MASK));
- req->val = cpu_to_be64(val);
+ req->word_cookie = htons(0);
+ req->mask = cpu_to_be64(0x3 << 4);
+ req->val = cpu_to_be64(((hcrc ? ULP_CRC_HEADER : 0) |
+ (dcrc ? ULP_CRC_DATA : 0)) << 4);
set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@@ -1477,6 +1477,10 @@ static void *t4_uld_add(const struct cxgb4_lld_info *lldi)
cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr);
cdev->itp = &cxgb4i_iscsi_transport;
+ cdev->pfvf = FW_VIID_PFN_GET(cxgb4_port_viid(lldi->ports[0])) << 8;
+ pr_info("cdev 0x%p,%s, pfvf %u.\n",
+ cdev, lldi->ports[0]->name, cdev->pfvf);
+
rc = cxgb4i_ddp_init(cdev);
if (rc) {
pr_info("t4 0x%p ddp init failed.\n", cdev);
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
index 342263b..1096026 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
@@ -23,6 +23,11 @@
#define CXGB4I_TX_HEADER_LEN \
(sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr))
+struct ulptx_idata {
+ __be32 cmd_more;
+ __be32 len;
+};
+
struct cpl_rx_data_ddp {
union opcode_tid ot;
__be16 urg;
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 43025b7..c57d59d 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -162,16 +162,6 @@ struct cxgbi_ddp_info {
#define PPOD_VALID(x) ((x) << PPOD_VALID_SHIFT)
#define PPOD_VALID_FLAG PPOD_VALID(1U)
-#define W_TCB_ULP_TYPE 0
-#define TCB_ULP_TYPE_SHIFT 0
-#define TCB_ULP_TYPE_MASK 0xfULL
-#define TCB_ULP_TYPE(x) ((x) << TCB_ULP_TYPE_SHIFT)
-
-#define W_TCB_ULP_RAW 0
-#define TCB_ULP_RAW_SHIFT 4
-#define TCB_ULP_RAW_MASK 0xffULL
-#define TCB_ULP_RAW(x) ((x) << TCB_ULP_RAW_SHIFT)
-
/*
* sge_opaque_hdr -
* Opaque version of structure the SGE stores at skb->head of TX_DATA packets
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.
^ permalink raw reply related
* [PATCH 1/4] cxgbi: renamed alloc_cpl to alloc_wr
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q
[PATCH 1/4] cxgbi: renamed alloc_cpl to alloc_wr
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
This patch renamed alloc_cpl() to alloc_wr().
Signed-off-by: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 18 +++++++++---------
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 28 ++++++++++++++--------------
drivers/scsi/cxgbi/libcxgbi.h | 5 ++---
3 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index a01c1e2..a2c207f 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -320,7 +320,7 @@ static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
"csk 0x%p,%u,0x%lx,%u, credit %u, dack %u.\n",
csk, csk->state, csk->flags, csk->tid, credits, dack);
- skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+ skb = alloc_wr(sizeof(*req), 0, GFP_ATOMIC);
if (!skb) {
pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
return 0;
@@ -572,7 +572,7 @@ static void act_open_retry_timer(unsigned long data)
cxgbi_sock_get(csk);
spin_lock_bh(&csk->lock);
- skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+ skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
if (!skb)
cxgbi_sock_fail_act_open(csk, -ENOMEM);
else {
@@ -881,16 +881,16 @@ static int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
*/
static int alloc_cpls(struct cxgbi_sock *csk)
{
- csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req), 0,
+ csk->cpl_close = alloc_wr(sizeof(struct cpl_close_con_req), 0,
GFP_KERNEL);
if (!csk->cpl_close)
return -ENOMEM;
- csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req), 0,
+ csk->cpl_abort_req = alloc_wr(sizeof(struct cpl_abort_req), 0,
GFP_KERNEL);
if (!csk->cpl_abort_req)
goto free_cpl_skbs;
- csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl), 0,
+ csk->cpl_abort_rpl = alloc_wr(sizeof(struct cpl_abort_rpl), 0,
GFP_KERNEL);
if (!csk->cpl_abort_rpl)
goto free_cpl_skbs;
@@ -972,7 +972,7 @@ static int init_act_open(struct cxgbi_sock *csk)
cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
cxgbi_sock_get(csk);
- skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
+ skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
if (!skb)
goto rel_resource;
skb->sk = (struct sock *)csk;
@@ -1141,7 +1141,7 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
"ddp 0x%p, idx %d, cnt %d.\n", ddp, idx, cnt);
for (i = 0; i < cnt; i++) {
- struct sk_buff *skb = alloc_cpl(sizeof(struct ulp_mem_io) +
+ struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
PPOD_SIZE, 0, gfp);
if (skb) {
ddp->gl_skb[idx + i] = skb;
@@ -1156,7 +1156,7 @@ static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
unsigned int tid, int pg_idx, bool reply)
{
- struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+ struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
GFP_KERNEL);
struct cpl_set_tcb_field *req;
u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
@@ -1193,7 +1193,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
int hcrc, int dcrc, int reply)
{
- struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+ struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
GFP_KERNEL);
struct cpl_set_tcb_field *req;
u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0);
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index b375a68..1056d97 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -332,7 +332,7 @@ static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
"csk 0x%p,%u,0x%lx,%u, credit %u.\n",
csk, csk->state, csk->flags, csk->tid, credits);
- skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+ skb = alloc_wr(sizeof(*req), 0, GFP_ATOMIC);
if (!skb) {
pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
return 0;
@@ -388,7 +388,7 @@ static inline void send_tx_flowc_wr(struct cxgbi_sock *csk)
int flowclen, i;
flowclen = 80;
- skb = alloc_cpl(flowclen, 0, GFP_ATOMIC);
+ skb = alloc_wr(flowclen, 0, GFP_ATOMIC);
flowc = (struct fw_flowc_wr *)skb->head;
flowc->op_to_nparams =
htonl(FW_WR_OP(FW_FLOWC_WR) | FW_FLOWC_WR_NPARAMS(8));
@@ -651,7 +651,7 @@ static void csk_act_open_retry_timer(unsigned long data)
cxgbi_sock_get(csk);
spin_lock_bh(&csk->lock);
- skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+ skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
if (!skb)
cxgbi_sock_fail_act_open(csk, -ENOMEM);
else {
@@ -1073,18 +1073,18 @@ static void do_set_tcb_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
static int alloc_cpls(struct cxgbi_sock *csk)
{
- csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req),
- 0, GFP_NOIO);
+ csk->cpl_close = alloc_wr(sizeof(struct cpl_close_con_req),
+ 0, GFP_KERNEL);
if (!csk->cpl_close)
return -ENOMEM;
- csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req),
- 0, GFP_NOIO);
+ csk->cpl_abort_req = alloc_wr(sizeof(struct cpl_abort_req),
+ 0, GFP_KERNEL);
if (!csk->cpl_abort_req)
goto free_cpls;
- csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl),
- 0, GFP_NOIO);
+ csk->cpl_abort_rpl = alloc_wr(sizeof(struct cpl_abort_rpl),
+ 0, GFP_KERNEL);
if (!csk->cpl_abort_rpl)
goto free_cpls;
return 0;
@@ -1158,7 +1158,7 @@ static int init_act_open(struct cxgbi_sock *csk)
}
cxgbi_sock_get(csk);
- skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_NOIO);
+ skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
if (!skb)
goto rel_resource;
skb->sk = (struct sock *)csk;
@@ -1268,7 +1268,7 @@ static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
dlen = PPOD_SIZE * npods;
pm_addr = idx * PPOD_SIZE + ddp->llimit;
- skb = alloc_cpl(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
+ skb = alloc_wr(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
if (!skb) {
pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
cdev, idx, npods);
@@ -1339,7 +1339,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
if (!pg_idx)
return 0;
- skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+ skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -1373,7 +1373,7 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
val = TCB_ULP_RAW(val);
val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
- skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+ skb = alloc_wr(sizeof(*req), 0, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -1516,7 +1516,7 @@ static int t4_uld_rx_handler(void *handle, const __be64 *rsp,
if (pgl == NULL) {
unsigned int len = 64 - sizeof(struct rsp_ctrl) - 8;
- skb = alloc_cpl(len, 0, GFP_ATOMIC);
+ skb = alloc_wr(len, 0, GFP_ATOMIC);
if (!skb)
goto nomem;
skb_copy_to_linear_data(skb, &rsp[1], len);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 40551f3..2f2485b 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -410,16 +410,15 @@ static inline unsigned int cxgbi_sock_compute_wscale(unsigned int win)
return wscale;
}
-static inline struct sk_buff *alloc_cpl(int cpl_len, int dlen, gfp_t gfp)
+static inline struct sk_buff *alloc_wr(int wrlen, int dlen, gfp_t gfp)
{
- int wrlen = roundup(cpl_len, 16);
struct sk_buff *skb = alloc_skb(wrlen + dlen, gfp);
if (skb) {
__skb_put(skb, wrlen);
memset(skb->head, 0, wrlen + dlen);
} else
- pr_info("alloc cpl skb %u+%u, OOM.\n", cpl_len, dlen);
+ pr_info("alloc cpl wr skb %u+%u, OOM.\n", wrlen, dlen);
return skb;
}
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.
^ permalink raw reply related
* [PATCH 0/4] cxgbi: bug fixes and driver update
From: kxie-ut6Up61K2wZBDgjK7y7TUQ @ 2010-09-23 23:43 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-scsi-u79uwXL29TY76Z2rM5mHXA,
open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: rranjan-ut6Up61K2wZBDgjK7y7TUQ, kxie-ut6Up61K2wZBDgjK7y7TUQ,
James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
michaelc-hcNo3dDEHLuVc3sceRu5cw, davem-fT/PcQaiUtIeIZ0/mPfg9Q
[PATCH 0/4] cxgbi: bug fixes and driver update
From: Karen Xie <kxie-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
This patchset includes:
- renamed alloc_cpl() to alloc_wr(),
- fixed locking in pdu read,
- fixed cxgb3i connecting over VLAN, and
- updated cxgb4i connection setting and ddp programming.
Thanks.
Karen
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.
^ permalink raw reply
* Re: [PATCH v4 0/2] Get and Set Feature Reports on HIDRAW (USB and Bluetooth)
From: Alan Ott @ 2010-09-23 23:40 UTC (permalink / raw)
To: Ville Tervo
Cc: Jiri Kosina, Stefan Achatz, Antonio Ospite, Alexey Dobriyan,
Tejun Heo, Alan Stern, Greg Kroah-Hartman, Marcel Holtmann,
Stephane Chatty, Michael Poole, David S. Miller, Bastien Nocera,
Eric Dumazet, linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-bluetooth-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20100923162521.GA15641@null>
On 09/23/2010 12:25 PM, Ville Tervo wrote:
> Hi Alan,
>
> On Mon, Aug 16, 2010 at 10:20:57PM +0200, ext Alan Ott wrote:
>
>> This is version 4. Built against 2.6.35+ revision 320b2b8de12698 .
>>
>
> I gave a try to to this patch using your test tool [1] and very old BT
> keyboard. I don't have anything else ATM to test with. Is there some BT hid
> devices which support setting and getting features?
>
A keyboard is the only BT device I've used which has feature reports.
> Shouldn't HIDIOCSFEATURE's bt version have similar wait as HIDIOCGFEATURE to
> get report status back from the device? or is there even any status coming back
> in successful case? Sorry I'm a newbie with HID and trying to understand how
> this should work.
>
> Now it just returns num of send bytes even if the remote device returned some
> error. Which one is the expected behavior?
>
I made it function the same as the existing hidp_output_raw_report().
Nothing in net/bluetooth/hidp/core.c is acked at all. I'm not sure of
the reasons.
Jiri, Marcel, any ideas?
> Other problem is that Get report is getting now handshake from set report.
>
>
>
Yeah, that makes sense. I hadn't considered the set_report failing. In
that case, I guess it means we _must_ wait for an ack for sent packets.
Anyone else agree or disagree?
Alan.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [net-next-2.6 PATCH] ixgbevf: Refactor ring parameter re-size
From: Jeff Kirsher @ 2010-09-23 22:46 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, bphilips, Greg Rose, Jeff Kirsher
From: Greg Rose <gregory.v.rose@intel.com>
The function to resize the Tx/Rx rings had the potential to
dereference a NULL pointer and the code would attempt to resize
the Tx ring even if the Rx ring allocation had failed. This
would cause some confusion in the return code semantics. Fixed
up to just unwind the allocations if any of them fail and return
an error.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbevf/ethtool.c | 153 +++++++++++++++++++++--------------------
1 files changed, 79 insertions(+), 74 deletions(-)
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 4680b06..4cc817a 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
- int i, err;
+ int i, err = 0;
u32 new_rx_count, new_tx_count;
- bool need_tx_update = false;
- bool need_rx_update = false;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state))
msleep(1);
- if (new_tx_count != adapter->tx_ring_count) {
- tx_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct ixgbevf_ring), GFP_KERNEL);
- if (!tx_ring) {
- err = -ENOMEM;
- goto err_setup;
- }
- memcpy(tx_ring, adapter->tx_ring,
- adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
- for (i = 0; i < adapter->num_tx_queues; i++) {
- tx_ring[i].count = new_tx_count;
- err = ixgbevf_setup_tx_resources(adapter,
- &tx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbevf_free_tx_resources(adapter,
- &tx_ring[i]);
- }
- kfree(tx_ring);
- goto err_setup;
- }
- tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
- }
- need_tx_update = true;
+ /*
+ * If the adapter isn't up and running then just set the
+ * new parameters and scurry for the exits.
+ */
+ if (!netif_running(adapter->netdev)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].count = new_tx_count;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].count = new_rx_count;
+ adapter->tx_ring_count = new_tx_count;
+ adapter->rx_ring_count = new_rx_count;
+ goto clear_reset;
}
- if (new_rx_count != adapter->rx_ring_count) {
- rx_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct ixgbevf_ring), GFP_KERNEL);
- if ((!rx_ring) && (need_tx_update)) {
- err = -ENOMEM;
- goto err_rx_setup;
- }
- memcpy(rx_ring, adapter->rx_ring,
- adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
- for (i = 0; i < adapter->num_rx_queues; i++) {
- rx_ring[i].count = new_rx_count;
- err = ixgbevf_setup_rx_resources(adapter,
- &rx_ring[i]);
- if (err) {
- while (i) {
- i--;
- ixgbevf_free_rx_resources(adapter,
- &rx_ring[i]);
- }
- kfree(rx_ring);
- goto err_rx_setup;
- }
- rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
- }
- need_rx_update = true;
+ tx_ring = kcalloc(adapter->num_tx_queues,
+ sizeof(struct ixgbevf_ring), GFP_KERNEL);
+ if (!tx_ring) {
+ err = -ENOMEM;
+ goto clear_reset;
}
-err_rx_setup:
- /* if rings need to be updated, here's the place to do it in one shot */
- if (need_tx_update || need_rx_update) {
- if (netif_running(netdev))
- ixgbevf_down(adapter);
+ rx_ring = kcalloc(adapter->num_rx_queues,
+ sizeof(struct ixgbevf_ring), GFP_KERNEL);
+ if (!rx_ring) {
+ err = -ENOMEM;
+ goto err_rx_setup;
}
- /* tx */
- if (need_tx_update) {
- kfree(adapter->tx_ring);
- adapter->tx_ring = tx_ring;
- tx_ring = NULL;
- adapter->tx_ring_count = new_tx_count;
+ ixgbevf_down(adapter);
+
+ memcpy(tx_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbevf_ring));
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ tx_ring[i].count = new_tx_count;
+ err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]);
+ if (err) {
+ while (i) {
+ i--;
+ ixgbevf_free_tx_resources(adapter,
+ &tx_ring[i]);
+ }
+ goto err_tx_ring_setup;
+ }
+ tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
}
- /* rx */
- if (need_rx_update) {
- kfree(adapter->rx_ring);
- adapter->rx_ring = rx_ring;
- rx_ring = NULL;
- adapter->rx_ring_count = new_rx_count;
+ memcpy(rx_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbevf_ring));
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rx_ring[i].count = new_rx_count;
+ err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]);
+ if (err) {
+ while (i) {
+ i--;
+ ixgbevf_free_rx_resources(adapter,
+ &rx_ring[i]);
+ }
+ goto err_rx_ring_setup;
+ }
+ rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
}
+ /*
+ * Only switch to new rings if all the prior allocations
+ * and ring setups have succeeded.
+ */
+ kfree(adapter->tx_ring);
+ adapter->tx_ring = tx_ring;
+ adapter->tx_ring_count = new_tx_count;
+
+ kfree(adapter->rx_ring);
+ adapter->rx_ring = rx_ring;
+ adapter->rx_ring_count = new_rx_count;
+
/* success! */
- err = 0;
- if (netif_running(netdev))
- ixgbevf_up(adapter);
+ ixgbevf_up(adapter);
+
+ goto clear_reset;
+
+err_rx_ring_setup:
+ for(i = 0; i < adapter->num_tx_queues; i++)
+ ixgbevf_free_tx_resources(adapter, &tx_ring[i]);
+
+err_tx_ring_setup:
+ kfree(rx_ring);
+
+err_rx_setup:
+ kfree(tx_ring);
-err_setup:
+clear_reset:
clear_bit(__IXGBEVF_RESETTING, &adapter->state);
return err;
}
^ permalink raw reply related
* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: Thomas Gleixner @ 2010-09-23 22:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Richard Cochran, LKML, John Stultz, Rodolfo Giometti,
Peter Zijlstra, linux-api-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
netdev-u79uwXL29TY76Z2rM5mHXA, Christoph Lameter,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, David Miller,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Krzysztof Halasa
In-Reply-To: <1285279423.5158.20.camel@pasglop>
On Fri, 24 Sep 2010, Benjamin Herrenschmidt wrote:
> On Thu, 2010-09-23 at 19:31 +0200, Richard Cochran wrote:
> > The new syscall, clock_adjtime, takes two parameters, the clock ID,
> > and a pointer to a struct timex. The semantics of the timex struct
> > have been expanded by one additional mode flag, which allows an
> > absolute offset correction. When specificied, the clock offset is
> > immediately corrected by adding the given time value to the current
> > time value.
>
> Any reason why you CC'ed device-tree discuss ?
>
> This list is getting way too much unrelated stuff, which I find
> annoying, it would be nice if we were all a bit more careful here with
> our CC lists.
Says the guy who missed to trim the useless context of the original
mail, which made me scroll down all the way just to find out that
there is nothing to see.
Thanks,
tglx
^ permalink raw reply
* [PATCH] smsc911x: Add MODULE_ALIAS()
From: Vincent @ 2010-09-23 22:08 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 189 bytes --]
Hi,
The smsc911x ethernet driver is lacking a module alias. This does
prevent auto-loading of the driver.
The attached patch fixes this. Please apply.
Best regards,
--
Vincent Stehlé
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-smsc911x-Add-MODULE_ALIAS.patch --]
[-- Type: text/x-patch; name="0001-smsc911x-Add-MODULE_ALIAS.patch", Size: 847 bytes --]
>From 54d0c88812d9707fc721ab4b6a2f669a44f873d7 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Vincent=20Stehl=C3=A9?= <vincent.stehle@laposte.net>
Date: Thu, 23 Sep 2010 23:19:14 +0200
Subject: [PATCH] smsc911x: Add MODULE_ALIAS()
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
This enables auto loading for the smsc911x ethernet driver.
Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net>
---
drivers/net/smsc911x.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 7a7b01a..1cf5b8a 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -58,6 +58,7 @@
MODULE_LICENSE("GPL");
MODULE_VERSION(SMSC_DRV_VERSION);
+MODULE_ALIAS("platform:smsc911x");
#if USE_DEBUG > 0
static int debug = 16;
--
1.5.6.5
^ permalink raw reply related
* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: Benjamin Herrenschmidt @ 2010-09-23 22:03 UTC (permalink / raw)
To: Richard Cochran
Cc: Peter Zijlstra, John Stultz,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Miller,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA,
Thomas Gleixner, Rodolfo Giometti, Christoph Lameter,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Krzysztof Halasa
In-Reply-To: <b94ef1cd9c04ef3ad5964408bd0af7251add78de.1285261534.git.richard.cochran-3mrvs1K0uXizZXS1Dc/lvw@public.gmane.org>
On Thu, 2010-09-23 at 19:31 +0200, Richard Cochran wrote:
> A new syscall is introduced that allows tuning of a POSIX clock. The
> syscall is implemented for four architectures: arm, blackfin, powerpc,
> and x86.
>
> The new syscall, clock_adjtime, takes two parameters, the clock ID,
> and a pointer to a struct timex. The semantics of the timex struct
> have been expanded by one additional mode flag, which allows an
> absolute offset correction. When specificied, the clock offset is
> immediately corrected by adding the given time value to the current
> time value.
Any reason why you CC'ed device-tree discuss ?
This list is getting way too much unrelated stuff, which I find
annoying, it would be nice if we were all a bit more careful here with
our CC lists.
Cheers,
Ben.
> Signed-off-by: Richard Cochran <richard.cochran-3mrvs1K0uXizZXS1Dc/lvw@public.gmane.org>
> ---
> arch/arm/include/asm/unistd.h | 1 +
> arch/arm/kernel/calls.S | 1 +
> arch/blackfin/include/asm/unistd.h | 3 +-
> arch/blackfin/mach-common/entry.S | 1 +
> arch/powerpc/include/asm/systbl.h | 1 +
> arch/powerpc/include/asm/unistd.h | 3 +-
> arch/x86/ia32/ia32entry.S | 1 +
> arch/x86/include/asm/unistd_32.h | 3 +-
> arch/x86/include/asm/unistd_64.h | 2 +
> arch/x86/kernel/syscall_table_32.S | 1 +
> include/linux/posix-timers.h | 3 +
> include/linux/syscalls.h | 2 +
> include/linux/timex.h | 3 +-
> kernel/compat.c | 136 +++++++++++++++++++++++-------------
> kernel/posix-cpu-timers.c | 4 +
> kernel/posix-timers.c | 17 +++++
> 16 files changed, 130 insertions(+), 52 deletions(-)
>
> diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
> index c891eb7..f58d881 100644
> --- a/arch/arm/include/asm/unistd.h
> +++ b/arch/arm/include/asm/unistd.h
> @@ -396,6 +396,7 @@
> #define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
> #define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
> #define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
> +#define __NR_clock_adjtime (__NR_SYSCALL_BASE+370)
>
> /*
> * The following SWIs are ARM private.
> diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
> index 5c26ecc..430de4c 100644
> --- a/arch/arm/kernel/calls.S
> +++ b/arch/arm/kernel/calls.S
> @@ -379,6 +379,7 @@
> CALL(sys_fanotify_init)
> CALL(sys_fanotify_mark)
> CALL(sys_prlimit64)
> +/* 370 */ CALL(sys_clock_adjtime)
> #ifndef syscalls_counted
> .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
> #define syscalls_counted
> diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
> index 14fcd25..79ad99b 100644
> --- a/arch/blackfin/include/asm/unistd.h
> +++ b/arch/blackfin/include/asm/unistd.h
> @@ -392,8 +392,9 @@
> #define __NR_fanotify_init 371
> #define __NR_fanotify_mark 372
> #define __NR_prlimit64 373
> +#define __NR_clock_adjtime 374
>
> -#define __NR_syscall 374
> +#define __NR_syscall 375
> #define NR_syscalls __NR_syscall
>
> /* Old optional stuff no one actually uses */
> diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
> index af1bffa..ee68730 100644
> --- a/arch/blackfin/mach-common/entry.S
> +++ b/arch/blackfin/mach-common/entry.S
> @@ -1631,6 +1631,7 @@ ENTRY(_sys_call_table)
> .long _sys_fanotify_init
> .long _sys_fanotify_mark
> .long _sys_prlimit64
> + .long _sys_clock_adjtime
>
> .rept NR_syscalls-(.-_sys_call_table)/4
> .long _sys_ni_syscall
> diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
> index 3d21266..2485d8f 100644
> --- a/arch/powerpc/include/asm/systbl.h
> +++ b/arch/powerpc/include/asm/systbl.h
> @@ -329,3 +329,4 @@ COMPAT_SYS(rt_tgsigqueueinfo)
> SYSCALL(fanotify_init)
> COMPAT_SYS(fanotify_mark)
> SYSCALL_SPU(prlimit64)
> +COMPAT_SYS_SPU(clock_adjtime)
> diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
> index 597e6f9..85d5067 100644
> --- a/arch/powerpc/include/asm/unistd.h
> +++ b/arch/powerpc/include/asm/unistd.h
> @@ -348,10 +348,11 @@
> #define __NR_fanotify_init 323
> #define __NR_fanotify_mark 324
> #define __NR_prlimit64 325
> +#define __NR_clock_adjtime 326
>
> #ifdef __KERNEL__
>
> -#define __NR_syscalls 326
> +#define __NR_syscalls 327
>
> #define __NR__exit __NR_exit
> #define NR_syscalls __NR_syscalls
> diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
> index 518bb99..0ed7896 100644
> --- a/arch/x86/ia32/ia32entry.S
> +++ b/arch/x86/ia32/ia32entry.S
> @@ -851,4 +851,5 @@ ia32_sys_call_table:
> .quad sys_fanotify_init
> .quad sys32_fanotify_mark
> .quad sys_prlimit64 /* 340 */
> + .quad compat_sys_clock_adjtime
> ia32_syscall_end:
> diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
> index b766a5e..b6f73f1 100644
> --- a/arch/x86/include/asm/unistd_32.h
> +++ b/arch/x86/include/asm/unistd_32.h
> @@ -346,10 +346,11 @@
> #define __NR_fanotify_init 338
> #define __NR_fanotify_mark 339
> #define __NR_prlimit64 340
> +#define __NR_clock_adjtime 341
>
> #ifdef __KERNEL__
>
> -#define NR_syscalls 341
> +#define NR_syscalls 342
>
> #define __ARCH_WANT_IPC_PARSE_VERSION
> #define __ARCH_WANT_OLD_READDIR
> diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
> index 363e9b8..5ee3085 100644
> --- a/arch/x86/include/asm/unistd_64.h
> +++ b/arch/x86/include/asm/unistd_64.h
> @@ -669,6 +669,8 @@ __SYSCALL(__NR_fanotify_init, sys_fanotify_init)
> __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
> #define __NR_prlimit64 302
> __SYSCALL(__NR_prlimit64, sys_prlimit64)
> +#define __NR_clock_adjtime 303
> +__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
>
> #ifndef __NO_STUBS
> #define __ARCH_WANT_OLD_READDIR
> diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
> index b35786d..68c7b9a 100644
> --- a/arch/x86/kernel/syscall_table_32.S
> +++ b/arch/x86/kernel/syscall_table_32.S
> @@ -340,3 +340,4 @@ ENTRY(sys_call_table)
> .long sys_fanotify_init
> .long sys_fanotify_mark
> .long sys_prlimit64 /* 340 */
> + .long sys_clock_adjtime
> diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
> index 3e23844..abf61cc 100644
> --- a/include/linux/posix-timers.h
> +++ b/include/linux/posix-timers.h
> @@ -4,6 +4,7 @@
> #include <linux/spinlock.h>
> #include <linux/list.h>
> #include <linux/sched.h>
> +#include <linux/timex.h>
>
> union cpu_time_count {
> cputime_t cpu;
> @@ -71,6 +72,7 @@ struct k_clock {
> int (*clock_getres) (const clockid_t which_clock, struct timespec *tp);
> int (*clock_set) (const clockid_t which_clock, struct timespec * tp);
> int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
> + int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
> int (*timer_create) (struct k_itimer *timer);
> int (*nsleep) (const clockid_t which_clock, int flags,
> struct timespec *, struct timespec __user *);
> @@ -97,6 +99,7 @@ int posix_timer_event(struct k_itimer *timr, int si_private);
> int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *ts);
> int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *ts);
> int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
> +int posix_cpu_clock_adj(const clockid_t which_clock, struct timex *tx);
> int posix_cpu_timer_create(struct k_itimer *timer);
> int posix_cpu_nsleep(const clockid_t which_clock, int flags,
> struct timespec *rqtp, struct timespec __user *rmtp);
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index e6319d1..0b24775 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -313,6 +313,8 @@ asmlinkage long sys_clock_settime(clockid_t which_clock,
> const struct timespec __user *tp);
> asmlinkage long sys_clock_gettime(clockid_t which_clock,
> struct timespec __user *tp);
> +asmlinkage long sys_clock_adjtime(clockid_t which_clock,
> + struct timex __user *tx);
> asmlinkage long sys_clock_getres(clockid_t which_clock,
> struct timespec __user *tp);
> asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags,
> diff --git a/include/linux/timex.h b/include/linux/timex.h
> index 32d852f..82d4b24 100644
> --- a/include/linux/timex.h
> +++ b/include/linux/timex.h
> @@ -73,7 +73,7 @@ struct timex {
> long tolerance; /* clock frequency tolerance (ppm)
> * (read only)
> */
> - struct timeval time; /* (read only) */
> + struct timeval time; /* (read only, except for ADJ_SETOFFSET) */
> long tick; /* (modified) usecs between clock ticks */
>
> long ppsfreq; /* pps frequency (scaled ppm) (ro) */
> @@ -101,6 +101,7 @@ struct timex {
> #define ADJ_ESTERROR 0x0008 /* estimated time error */
> #define ADJ_STATUS 0x0010 /* clock status */
> #define ADJ_TIMECONST 0x0020 /* pll time constant */
> +#define ADJ_SETOFFSET 0x0040 /* add 'time' to current time */
> #define ADJ_TAI 0x0080 /* set TAI offset */
> #define ADJ_MICRO 0x1000 /* select microsecond resolution */
> #define ADJ_NANO 0x2000 /* select nanosecond resolution */
> diff --git a/kernel/compat.c b/kernel/compat.c
> index c9e2ec0..38b1d2c 100644
> --- a/kernel/compat.c
> +++ b/kernel/compat.c
> @@ -52,6 +52,64 @@ static int compat_put_timeval(struct compat_timeval __user *o,
> put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
> }
>
> +static int compat_get_timex(struct timex *txc, struct compat_timex __user *utp)
> +{
> + memset(txc, 0, sizeof(struct timex));
> +
> + if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
> + __get_user(txc->modes, &utp->modes) ||
> + __get_user(txc->offset, &utp->offset) ||
> + __get_user(txc->freq, &utp->freq) ||
> + __get_user(txc->maxerror, &utp->maxerror) ||
> + __get_user(txc->esterror, &utp->esterror) ||
> + __get_user(txc->status, &utp->status) ||
> + __get_user(txc->constant, &utp->constant) ||
> + __get_user(txc->precision, &utp->precision) ||
> + __get_user(txc->tolerance, &utp->tolerance) ||
> + __get_user(txc->time.tv_sec, &utp->time.tv_sec) ||
> + __get_user(txc->time.tv_usec, &utp->time.tv_usec) ||
> + __get_user(txc->tick, &utp->tick) ||
> + __get_user(txc->ppsfreq, &utp->ppsfreq) ||
> + __get_user(txc->jitter, &utp->jitter) ||
> + __get_user(txc->shift, &utp->shift) ||
> + __get_user(txc->stabil, &utp->stabil) ||
> + __get_user(txc->jitcnt, &utp->jitcnt) ||
> + __get_user(txc->calcnt, &utp->calcnt) ||
> + __get_user(txc->errcnt, &utp->errcnt) ||
> + __get_user(txc->stbcnt, &utp->stbcnt))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int compat_put_timex(struct compat_timex __user *utp, struct timex *txc)
> +{
> + if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
> + __put_user(txc->modes, &utp->modes) ||
> + __put_user(txc->offset, &utp->offset) ||
> + __put_user(txc->freq, &utp->freq) ||
> + __put_user(txc->maxerror, &utp->maxerror) ||
> + __put_user(txc->esterror, &utp->esterror) ||
> + __put_user(txc->status, &utp->status) ||
> + __put_user(txc->constant, &utp->constant) ||
> + __put_user(txc->precision, &utp->precision) ||
> + __put_user(txc->tolerance, &utp->tolerance) ||
> + __put_user(txc->time.tv_sec, &utp->time.tv_sec) ||
> + __put_user(txc->time.tv_usec, &utp->time.tv_usec) ||
> + __put_user(txc->tick, &utp->tick) ||
> + __put_user(txc->ppsfreq, &utp->ppsfreq) ||
> + __put_user(txc->jitter, &utp->jitter) ||
> + __put_user(txc->shift, &utp->shift) ||
> + __put_user(txc->stabil, &utp->stabil) ||
> + __put_user(txc->jitcnt, &utp->jitcnt) ||
> + __put_user(txc->calcnt, &utp->calcnt) ||
> + __put_user(txc->errcnt, &utp->errcnt) ||
> + __put_user(txc->stbcnt, &utp->stbcnt) ||
> + __put_user(txc->tai, &utp->tai))
> + return -EFAULT;
> + return 0;
> +}
> +
> asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
> struct timezone __user *tz)
> {
> @@ -617,6 +675,29 @@ long compat_sys_clock_gettime(clockid_t which_clock,
> return err;
> }
>
> +long compat_sys_clock_adjtime(clockid_t which_clock,
> + struct compat_timex __user *utp)
> +{
> + struct timex txc;
> + mm_segment_t oldfs;
> + int err, ret;
> +
> + err = compat_get_timex(&txc, utp);
> + if (err)
> + return err;
> +
> + oldfs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_clock_adjtime(which_clock, (struct timex __user *) &txc);
> + set_fs(oldfs);
> +
> + err = compat_put_timex(utp, &txc);
> + if (err)
> + return err;
> +
> + return ret;
> +}
> +
> long compat_sys_clock_getres(clockid_t which_clock,
> struct compat_timespec __user *tp)
> {
> @@ -951,58 +1032,17 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
> asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp)
> {
> struct timex txc;
> - int ret;
> -
> - memset(&txc, 0, sizeof(struct timex));
> + int err, ret;
>
> - if (!access_ok(VERIFY_READ, utp, sizeof(struct compat_timex)) ||
> - __get_user(txc.modes, &utp->modes) ||
> - __get_user(txc.offset, &utp->offset) ||
> - __get_user(txc.freq, &utp->freq) ||
> - __get_user(txc.maxerror, &utp->maxerror) ||
> - __get_user(txc.esterror, &utp->esterror) ||
> - __get_user(txc.status, &utp->status) ||
> - __get_user(txc.constant, &utp->constant) ||
> - __get_user(txc.precision, &utp->precision) ||
> - __get_user(txc.tolerance, &utp->tolerance) ||
> - __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
> - __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
> - __get_user(txc.tick, &utp->tick) ||
> - __get_user(txc.ppsfreq, &utp->ppsfreq) ||
> - __get_user(txc.jitter, &utp->jitter) ||
> - __get_user(txc.shift, &utp->shift) ||
> - __get_user(txc.stabil, &utp->stabil) ||
> - __get_user(txc.jitcnt, &utp->jitcnt) ||
> - __get_user(txc.calcnt, &utp->calcnt) ||
> - __get_user(txc.errcnt, &utp->errcnt) ||
> - __get_user(txc.stbcnt, &utp->stbcnt))
> - return -EFAULT;
> + err = compat_get_timex(&txc, utp);
> + if (err)
> + return err;
>
> ret = do_adjtimex(&txc);
>
> - if (!access_ok(VERIFY_WRITE, utp, sizeof(struct compat_timex)) ||
> - __put_user(txc.modes, &utp->modes) ||
> - __put_user(txc.offset, &utp->offset) ||
> - __put_user(txc.freq, &utp->freq) ||
> - __put_user(txc.maxerror, &utp->maxerror) ||
> - __put_user(txc.esterror, &utp->esterror) ||
> - __put_user(txc.status, &utp->status) ||
> - __put_user(txc.constant, &utp->constant) ||
> - __put_user(txc.precision, &utp->precision) ||
> - __put_user(txc.tolerance, &utp->tolerance) ||
> - __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
> - __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
> - __put_user(txc.tick, &utp->tick) ||
> - __put_user(txc.ppsfreq, &utp->ppsfreq) ||
> - __put_user(txc.jitter, &utp->jitter) ||
> - __put_user(txc.shift, &utp->shift) ||
> - __put_user(txc.stabil, &utp->stabil) ||
> - __put_user(txc.jitcnt, &utp->jitcnt) ||
> - __put_user(txc.calcnt, &utp->calcnt) ||
> - __put_user(txc.errcnt, &utp->errcnt) ||
> - __put_user(txc.stbcnt, &utp->stbcnt) ||
> - __put_user(txc.tai, &utp->tai))
> - ret = -EFAULT;
> + err = compat_put_timex(utp, &txc);
> + if (err)
> + return err;
>
> return ret;
> }
> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
> index 6842eeb..e1c2e7b 100644
> --- a/kernel/posix-cpu-timers.c
> +++ b/kernel/posix-cpu-timers.c
> @@ -207,6 +207,10 @@ int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
> return error;
> }
>
> +int posix_cpu_clock_adj(const clockid_t which_clock, struct timex *tx)
> +{
> + return -EOPNOTSUPP;
> +}
>
> /*
> * Sample a per-thread clock for the given task.
> diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
> index 9ca4973..446b566 100644
> --- a/kernel/posix-timers.c
> +++ b/kernel/posix-timers.c
> @@ -197,6 +197,14 @@ static int common_timer_create(struct k_itimer *new_timer)
> return 0;
> }
>
> +static inline int common_clock_adj(const clockid_t which_clock, struct timex *t)
> +{
> + if (CLOCK_REALTIME == which_clock)
> + return do_adjtimex(t);
> + else
> + return -EOPNOTSUPP;
> +}
> +
> static int no_timer_create(struct k_itimer *new_timer)
> {
> return -EOPNOTSUPP;
> @@ -969,6 +977,15 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
>
> }
>
> +SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
> + struct timex __user *, tx)
> +{
> + if (invalid_clockid(which_clock))
> + return -EINVAL;
> +
> + return CLOCK_DISPATCH(which_clock, clock_adj, (which_clock, tx));
> +}
> +
> SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
> struct timespec __user *, tp)
> {
^ permalink raw reply
* Re: [PATCH v6 0/8] ptp: IEEE 1588 hardware clock support
From: john stultz @ 2010-09-23 22:03 UTC (permalink / raw)
To: Alan Cox
Cc: Richard Cochran, linux-kernel, devicetree-discuss, linux-api,
linux-arm-kernel, linuxppc-dev, netdev, Arnd Bergmann,
Christoph Lameter, David Miller, Krzysztof Halasa, Peter Zijlstra,
Rodolfo Giometti, Thomas Gleixner
In-Reply-To: <20100923223025.2877cce2@lxorguk.ukuu.org.uk>
On Thu, 2010-09-23 at 22:30 +0100, Alan Cox wrote:
> O> I don't see how this is a problem, as it exposes the multiple hardware
> > clocks via different posix clock ids. So in the boundary clock case, you
> > can configure which side is the client and which side is the master in a
> > config file and the PTPd will appropriately steer them individually.
>
> They may all be slaves - that means you can't treat them as part of
> system time.
Sure, and that's something one would configure. So I'm not sure I see
how exposing the different hardware bits via a clock_id is problematic.
They're just clocks that are being exposed. The steering of system time
to PTP or PTP to system time (or just PTP to other PTP clocks).
> > on module unload, but I don't think we need a use-count to prevent the
> > module from being unloaded.
> >
> > My question would be: How do we handle a USB network device ($14.99 now
> > with PTP!) being unplugged? We can't say "Sorry! That's in use!". So we
> > note the hardware is gone, and return the proper error code.
> >
> > Or am I missing something else?
>
> Open list
> Oh number 31 appears to be the device I want
> Close list
>
> USB unplugged
> Random other device plugged
>
> clock_op(31, ....)
>
> Oh bugger I've just reprogrammed the wrong time source.
Ok. So its just the issue of clock_id reuse. I was confusing it with
some sort of module use counting issue. And yea, I can see how it might
be easier to re-use the file descriptor then re-implementing the reuse
logic in the posix-clock registration.
> We don't have stop the device being removed, instead of a disaster you get
>
> clock_op(fd, blah)
> -ENODEV
>
> which btw is how just about everything else USB works when you pull the
> hardware.
Right, which was what I was thinking as well, but assuming we didn't
re-use clockids quickly.
> > So, I don't really see how that's so different from what is being
> > proposed. The clock_id is dynamically assigned per registered clock, and
> > exposed via the sysfs interface from ptp hardware entry.
> >
> > The only difference is the open/close reference counting, which I don't
> > think is necessary here (since we can't always keep the hardware from
> > going away).
>
> It is absolutely neccessary in order that you can be sure that two calls
> actually relate to the *same* device. It's as fundamental as the
> difference betweeh chmod and fchmod although with the added ugliness of
> some random numeric identifier stuck in the middle.
>
> It also btw makes it much easier to fix up the existing random collection
> of /dev/rtc devices - because you can open them and issue fclock_adjtime
> if we are careful how we do it and it makes sense.
Wait, you're suggesting we add new fclock_* calls that duplicate the
posix interface? That doesn't sound great to me.
What did you think of Kyle Moffett's suggestion of utilizing the fd to
map to the clock_id which could then be used by the posix clocks
interface?
Although I'm still not sure if it wouldn't be so hard to just simply
increment the id on each registration and index to a clock through a
reasonably small hash table. I suspect that would solve the
enumeration/reuse issue without much trouble (but again, I'm open to
being corrected if I'm missing something larger).
But yes, in summary, this is an issue to be addressed one way or
another.
thanks
-john
^ permalink raw reply
* [PATCH ethtool 7/7] ethtool: Add my authorship and Solarflare copyright notice
From: Ben Hutchings @ 2010-09-23 21:50 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
AUTHORS | 1 +
ethtool.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 77500ce..aed04fa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,3 +6,4 @@ Eli Kupermann <eli.kupermann@intel.com>
Chris Leech <christopher.leech@intel.com>
Scott Feldman <scott.feldman@intel.com>
Andi Kleen
+Ben Hutchings <bhutchings@solarflare.com>
diff --git a/ethtool.c b/ethtool.c
index 31158f8..7612b14 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -14,6 +14,8 @@
* amd8111e support by Reeja John <reeja.john@amd.com>
* long arguments by Andi Kleen.
* SMSC LAN911x support by Steve Glendinning <steve.glendinning@smsc.com>
+ * Various features by Ben Hutchings <bhutchings@solarflare.com>;
+ * Copyright 2009, 2010 Solarflare Communications
*
* TODO:
* * no-args => summary of each device (mii-tool style)
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 6/7] ethtool: Update sfc register dump
From: Ben Hutchings @ 2010-09-23 21:50 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Add length checks to allow for extensions to the register dump without
changing the version number.
Show the RX IP filter table if present.
Fix address field definitions for the MAC filter tables.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
sfc.c | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/sfc.c b/sfc.c
index 2e4735f..c8ca74a 100644
--- a/sfc.c
+++ b/sfc.c
@@ -2420,8 +2420,8 @@
#define FRF_CZ_RMFT_RXQ_ID_WIDTH 12
#define FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60
#define FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1
-#define FRF_CZ_RMFT_DEST_MAC_LBN 16
-#define FRF_CZ_RMFT_DEST_MAC_WIDTH 44
+#define FRF_CZ_RMFT_DEST_MAC_LBN 12
+#define FRF_CZ_RMFT_DEST_MAC_WIDTH 48
#define FRF_CZ_RMFT_VLAN_ID_LBN 0
#define FRF_CZ_RMFT_VLAN_ID_WIDTH 12
@@ -2497,8 +2497,8 @@
#define FRF_CZ_TMFT_TXQ_ID_WIDTH 12
#define FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60
#define FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1
-#define FRF_CZ_TMFT_SRC_MAC_LBN 16
-#define FRF_CZ_TMFT_SRC_MAC_WIDTH 44
+#define FRF_CZ_TMFT_SRC_MAC_LBN 12
+#define FRF_CZ_TMFT_SRC_MAC_WIDTH 48
#define FRF_CZ_TMFT_VLAN_ID_LBN 0
#define FRF_CZ_TMFT_VLAN_ID_WIDTH 12
@@ -3445,9 +3445,11 @@ static const struct efx_nic_reg_field efx_nic_reg_fields_BUF_FULL_TBL[] = {
};
#define efx_nic_reg_fields_BUF_FULL_TBL_KER efx_nic_reg_fields_BUF_FULL_TBL
static const struct efx_nic_reg_field efx_nic_reg_fields_RX_FILTER_TBL0[] = {
- REGISTER_FIELD_BZ(SRC_TCP_DEST_UDP),
+ /* Source port for full match; destination port for UDP wild match */
+ REGISTER_FIELD_BZ_RENAME(SRC_TCP_DEST_UDP, "SRC_PORT"),
REGISTER_FIELD_BZ(SRC_IP),
- REGISTER_FIELD_BZ(DEST_PORT_TCP),
+ /* Destination port for full match or TCP wild match */
+ REGISTER_FIELD_BZ_RENAME(DEST_PORT_TCP, "DEST_PORT"),
REGISTER_FIELD_BZ(DEST_IP),
REGISTER_FIELD_BZ(RXQ_ID),
REGISTER_FIELD_BZ(TCP_UDP),
@@ -3663,8 +3665,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
- /* The register buffer is allocated with slab, so we can't
- * reasonably read all of the buffer table (up to 8MB!).
+ /* We can't reasonably read all of the buffer table (up to 8MB!).
* However this driver will only use a few entries. Reading
* 1K entries allows for some expansion of queue count and
* size before we need to change the version. */
@@ -3672,7 +3673,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
A, A, 8, 1024),
REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
B, Z, 8, 1024),
- /* RX_FILTER_TBL{0,1} is huge and not used by this driver */
REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
REGISTER_TABLE_BB_CZ(TIMER_TBL),
REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
@@ -3682,6 +3682,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
REGISTER_TABLE_CZ(MC_TREG_SMEM),
/* MSIX_PBA_TABLE is not mapped */
/* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
+ REGISTER_TABLE_BZ(RX_FILTER_TBL0),
};
static size_t column_width(const struct efx_nic_reg_field *field)
@@ -3830,12 +3831,13 @@ sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
const struct efx_nic_reg_table *table;
unsigned revision = regs->version;
const void *buf = regs->data;
+ const void *end = regs->data + regs->len;
if (revision > REGISTER_REVISION_Z)
return -1;
for (reg = efx_nic_regs;
- reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs);
+ reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs) && buf < end;
reg++) {
if (revision >= reg->min_revision &&
revision <= reg->max_revision)
@@ -3843,7 +3845,8 @@ sfc_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
}
for (table = efx_nic_reg_tables;
- table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables);
+ table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables) &&
+ buf < end;
table++) {
if (revision >= table->min_revision &&
revision <= table->max_revision) {
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 5/7] ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action
From: Ben Hutchings @ 2010-09-23 21:49 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8 | 48 ++++++++++++++++++++++++++++++++++++++----
ethtool.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 103 insertions(+), 13 deletions(-)
diff --git a/ethtool.8 b/ethtool.8
index 295caab..2c54cb4 100644
--- a/ethtool.8
+++ b/ethtool.8
@@ -233,8 +233,9 @@ ethtool \- Display or change ethernet card settings
.B ethtool \-u|\-\-show\-ntuple
.I ethX
-.B ethtool \-U|\-\-config\-ntuple
-.I ethX
+.TP
+.BI ethtool\ \-U|\-\-config\-ntuple \ ethX
+.RB {
.A3 flow-type tcp4 udp4 sctp4
.RB [ src-ip
.IR addr
@@ -252,6 +253,21 @@ ethtool \- Display or change ethernet card settings
.IR port
.RB [ dst-port-mask
.IR mask ]]
+.br
+.RB | \ flow-type\ ether
+.RB [ src
+.IR mac-addr
+.RB [ src-mask
+.IR mask ]]
+.RB [ dst
+.IR mac-addr
+.RB [ dst-mask
+.IR mask ]]
+.RB [ proto
+.IR N
+.RB [ proto-mask
+.IR mask ]]\ }
+.br
.RB [ vlan
.IR VLAN-tag
.RB [ vlan-mask
@@ -649,7 +665,7 @@ Get Rx ntuple filters and actions, then display them to the user.
.B \-U \-\-config-ntuple
Configure Rx ntuple filters and actions
.TP
-.B flow-type tcp4|udp4|sctp4
+.B flow-type tcp4|udp4|sctp4|ether
.RS
.PD 0
.TP 3
@@ -658,6 +674,8 @@ Configure Rx ntuple filters and actions
.BR "udp4" " UDP over IPv4"
.TP 3
.BR "sctp4" " SCTP over IPv4"
+.TP 3
+.BR "ether" " Ethernet"
.PD
.RE
.TP
@@ -686,6 +704,25 @@ Includes the destination port.
.BI dst-port-mask \ mask
Specify a mask for the destination port.
.TP
+.BI src \ mac-addr
+Includes the source MAC address, specified as 6 bytes in hexadecimal
+separated by colons.
+.TP
+.BI src-mask \ mask
+Specify a mask for the source MAC address.
+.TP
+.BI dst \ mac-addr
+Includes the destination MAC address.
+.TP
+.BI dst-mask \ mask
+Specify a mask for the destination MAC address.
+.TP
+.BI proto \ N
+Includes the Ethernet protocol number (ethertype).
+.TP
+.BI proto-mask \ mask
+Specify a mask for the Ethernet protocol number.
+.TP
.BI vlan \ VLAN-tag
Includes the VLAN tag.
.TP
@@ -699,11 +736,12 @@ Includes 64-bits of user-specific data.
Specify a mask for the user-specific data.
.TP
.BI action \ N
-Specifies either the Rx queue to send packets to, or to drop
-the matched flow.
+Specifies the Rx queue to send packets to, or some other action.
.RS
.PD 0
.TP 3
+.BR "-2" " Clear the filter"
+.TP 3
.BR "-1" " Drop the matched flow"
.TP 3
.BR "0 or higher" " Rx queue to route the flow"
diff --git a/ethtool.c b/ethtool.c
index ea6a26f..31158f8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -240,11 +240,15 @@ static struct option {
" equal N | weight W0 W1 ...\n" },
{ "-U", "--config-ntuple", MODE_SNTUPLE, "Configure Rx ntuple filters "
"and actions",
- " flow-type tcp4|udp4|sctp4\n"
- " [ src-ip ADDR [src-ip-mask MASK] ]\n"
- " [ dst-ip ADDR [dst-ip-mask MASK] ]\n"
- " [ src-port PORT [src-port-mask MASK] ]\n"
- " [ dst-port PORT [dst-port-mask MASK] ]\n"
+ " { flow-type tcp4|udp4|sctp4\n"
+ " [ src-ip ADDR [src-ip-mask MASK] ]\n"
+ " [ dst-ip ADDR [dst-ip-mask MASK] ]\n"
+ " [ src-port PORT [src-port-mask MASK] ]\n"
+ " [ dst-port PORT [dst-port-mask MASK] ]\n"
+ " | flow-type ether\n"
+ " [ src MAC-ADDR [src-mask MASK] ]\n"
+ " [ dst MAC-ADDR [dst-mask MASK] ]\n"
+ " [ proto N [proto-mask MASK] ] }\n"
" [ vlan VLAN-TAG [vlan-mask MASK] ]\n"
" [ user-def DATA [user-def-mask MASK] ]\n"
" action N\n" },
@@ -377,6 +381,12 @@ static int ntuple_psrc_seen = 0;
static int ntuple_psrc_mask_seen = 0;
static int ntuple_pdst_seen = 0;
static int ntuple_pdst_mask_seen = 0;
+static int ntuple_ether_dst_seen = 0;
+static int ntuple_ether_dst_mask_seen = 0;
+static int ntuple_ether_src_seen = 0;
+static int ntuple_ether_src_mask_seen = 0;
+static int ntuple_ether_proto_seen = 0;
+static int ntuple_ether_proto_mask_seen = 0;
static int ntuple_vlan_tag_seen = 0;
static int ntuple_vlan_tag_mask_seen = 0;
static int ntuple_user_def_seen = 0;
@@ -497,7 +507,7 @@ static struct cmdline_info cmdline_coalesce[] = {
{ "tx-frames-high", CMDL_S32, &coal_tx_frames_high_wanted, &ecoal.tx_max_coalesced_frames_high },
};
-static struct cmdline_info cmdline_ntuple[] = {
+static struct cmdline_info cmdline_ntuple_tcp_ip4[] = {
{ "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL,
0, &ntuple_ip4src_seen },
{ "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL,
@@ -525,6 +535,30 @@ static struct cmdline_info cmdline_ntuple[] = {
{ "action", CMDL_S32, &ntuple_fs.action, NULL },
};
+static struct cmdline_info cmdline_ntuple_ether[] = {
+ { "dst", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_dest, NULL,
+ 0, &ntuple_ether_dst_seen },
+ { "dst-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_dest, NULL,
+ 0, &ntuple_ether_dst_mask_seen },
+ { "src", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_source, NULL,
+ 0, &ntuple_ether_src_seen },
+ { "src-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_source, NULL,
+ 0, &ntuple_ether_src_mask_seen },
+ { "proto", CMDL_BE16, &ntuple_fs.h_u.ether_spec.h_proto, NULL,
+ 0, &ntuple_ether_proto_seen },
+ { "proto-mask", CMDL_BE16, &ntuple_fs.m_u.ether_spec.h_proto, NULL,
+ 0, &ntuple_ether_proto_mask_seen },
+ { "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL,
+ 0, &ntuple_vlan_tag_seen },
+ { "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL,
+ 0, &ntuple_vlan_tag_mask_seen },
+ { "user-def", CMDL_U64, &ntuple_fs.data, NULL,
+ 0, &ntuple_user_def_seen },
+ { "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL,
+ 0, &ntuple_user_def_mask_seen },
+ { "action", CMDL_S32, &ntuple_fs.action, NULL },
+};
+
static struct cmdline_info cmdline_msglvl[] = {
{ "drv", CMDL_FLAG, &msglvl_wanted, NULL,
NETIF_MSG_DRV, &msglvl_mask },
@@ -741,6 +775,8 @@ static int rxflow_str_to_type(const char *str)
flow_type = AH_ESP_V6_FLOW;
else if (!strcmp(str, "sctp6"))
flow_type = SCTP_V6_FLOW;
+ else if (!strcmp(str, "ether"))
+ flow_type = ETHER_FLOW;
return flow_type;
}
@@ -1551,8 +1587,8 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
case SCTP_V4_FLOW:
parse_generic_cmdline(argc, argp, i + 1,
&sntuple_changed,
- cmdline_ntuple,
- ARRAY_SIZE(cmdline_ntuple));
+ cmdline_ntuple_tcp_ip4,
+ ARRAY_SIZE(cmdline_ntuple_tcp_ip4));
if (!ntuple_ip4src_seen)
ntuple_fs.m_u.tcp_ip4_spec.ip4src = 0xffffffff;
if (!ntuple_ip4dst_seen)
@@ -1563,6 +1599,19 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
ntuple_fs.m_u.tcp_ip4_spec.pdst = 0xffff;
ntuple_fs.m_u.tcp_ip4_spec.tos = 0xff;
break;
+ case ETHER_FLOW:
+ parse_generic_cmdline(argc, argp, i + 1,
+ &sntuple_changed,
+ cmdline_ntuple_ether,
+ ARRAY_SIZE(cmdline_ntuple_ether));
+ if (!ntuple_ether_dst_seen)
+ memset(ntuple_fs.m_u.ether_spec.h_dest, 0xff, ETH_ALEN);
+ if (!ntuple_ether_src_seen)
+ memset(ntuple_fs.m_u.ether_spec.h_source, 0xff,
+ ETH_ALEN);
+ if (!ntuple_ether_proto_seen)
+ ntuple_fs.m_u.ether_spec.h_proto = 0xffff;
+ break;
default:
fprintf(stderr, "Unsupported flow type \"%s\"\n", argp[i]);
exit(106);
@@ -1578,6 +1627,9 @@ static void parse_rxntupleopts(int argc, char **argp, int i)
(ntuple_ip4dst_mask_seen && !ntuple_ip4dst_seen) ||
(ntuple_psrc_mask_seen && !ntuple_psrc_seen) ||
(ntuple_pdst_mask_seen && !ntuple_pdst_seen) ||
+ (ntuple_ether_dst_mask_seen && !ntuple_ether_dst_seen) ||
+ (ntuple_ether_src_mask_seen && !ntuple_ether_src_seen) ||
+ (ntuple_ether_proto_mask_seen && !ntuple_ether_proto_seen) ||
(ntuple_vlan_tag_mask_seen && !ntuple_vlan_tag_seen) ||
(ntuple_user_def_mask_seen && !ntuple_user_def_seen)) {
fprintf(stderr, "Cannot specify mask without value\n");
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 4/7] ethtool: Add MAC parameter type based on the parse_sopass() function
From: Ben Hutchings @ 2010-09-23 21:49 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 6ec1cac..ea6a26f 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -77,7 +77,7 @@ enum {
static int parse_wolopts(char *optstr, u32 *data);
static char *unparse_wolopts(int wolopts);
-static int parse_sopass(char *src, unsigned char *dest);
+static void get_mac_addr(char *src, unsigned char *dest);
static int do_gdrv(int fd, struct ifreq *ifr);
static int do_gset(int fd, struct ifreq *ifr);
static int do_sset(int fd, struct ifreq *ifr);
@@ -405,14 +405,15 @@ typedef enum {
CMDL_IP4,
CMDL_STR,
CMDL_FLAG,
+ CMDL_MAC,
} cmdline_type_t;
struct cmdline_info {
const char *name;
cmdline_type_t type;
- /* Points to int (BOOL), s32, u16, u32 (U32/FLAG/IP4), u64 or
- * char * (STR). For FLAG, the value accumulates all flags
- * to be set. */
+ /* Points to int (BOOL), s32, u16, u32 (U32/FLAG/IP4), u64,
+ * char * (STR) or u8[6] (MAC). For FLAG, the value accumulates
+ * all flags to be set. */
void *wanted_val;
void *ioctl_val;
/* For FLAG, the flag value to be set/cleared */
@@ -668,6 +669,10 @@ static void parse_generic_cmdline(int argc, char **argp,
*p = in.s_addr;
break;
}
+ case CMDL_MAC:
+ get_mac_addr(argp[i],
+ info[idx].wanted_val);
+ break;
case CMDL_FLAG: {
u32 *p;
p = info[idx].seen_val;
@@ -1044,8 +1049,7 @@ static void parse_cmdline(int argc, char **argp)
i++;
if (i >= argc)
show_usage(1);
- if (parse_sopass(argp[i], sopass_wanted) < 0)
- show_usage(1);
+ get_mac_addr(argp[i], sopass_wanted);
sopass_change = 1;
break;
} else if (!strcmp(argp[i], "msglvl")) {
@@ -1449,22 +1453,20 @@ static char *unparse_wolopts(int wolopts)
return buf;
}
-static int parse_sopass(char *src, unsigned char *dest)
+static void get_mac_addr(char *src, unsigned char *dest)
{
int count;
int i;
- int buf[SOPASS_MAX];
+ int buf[ETH_ALEN];
count = sscanf(src, "%2x:%2x:%2x:%2x:%2x:%2x",
&buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5]);
- if (count != SOPASS_MAX) {
- return -1;
- }
+ if (count != ETH_ALEN)
+ show_usage(1);
for (i = 0; i < count; i++) {
dest[i] = buf[i];
}
- return 0;
}
static int parse_rxfhashopts(char *optstr, u32 *data)
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 3/7] ethtool: Fix RX n-tuple masks and documentation
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers, Peter Waskiewicz
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
For fields with unspecified values, explicitly mask all bits. Do not
allow specifying a mask without a value.
Change usage information to clarify which parameters are optional or
required.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8 | 31 ++++++++--------
ethtool.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 105 insertions(+), 41 deletions(-)
diff --git a/ethtool.8 b/ethtool.8
index 3ca403c..295caab 100644
--- a/ethtool.8
+++ b/ethtool.8
@@ -235,34 +235,33 @@ ethtool \- Display or change ethernet card settings
.B ethtool \-U|\-\-config\-ntuple
.I ethX
-.RB [ flow-type
-.RB tcp4|udp4|sctp4 ]
+.A3 flow-type tcp4 udp4 sctp4
.RB [ src-ip
-.IR addr ]
+.IR addr
.RB [ src-ip-mask
-.IR mask ]
+.IR mask ]]
.RB [ dst-ip
-.IR addr ]
+.IR addr
.RB [ dst-ip-mask
-.IR mask ]
+.IR mask ]]
.RB [ src-port
-.IR port ]
+.IR port
.RB [ src-port-mask
-.IR mask ]
+.IR mask ]]
.RB [ dst-port
-.IR port ]
+.IR port
.RB [ dst-port-mask
-.IR mask ]
+.IR mask ]]
.RB [ vlan
-.IR VLAN-tag ]
+.IR VLAN-tag
.RB [ vlan-mask
-.IR mask ]
+.IR mask ]]
.RB [ user-def
-.IR data ]
+.IR data
.RB [ user-def-mask
-.IR mask ]
-.RB [ action
-.IR queue\ or\ drop ]
+.IR mask ]]
+.RI action \ N
+
.SH DESCRIPTION
.BI ethtool
is used for querying settings of an ethernet device and changing them.
diff --git a/ethtool.c b/ethtool.c
index 8c5d595..6ec1cac 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -99,6 +99,7 @@ static int do_gstats(int fd, struct ifreq *ifr);
static int rxflow_str_to_type(const char *str);
static int parse_rxfhashopts(char *optstr, u32 *data);
static char *unparse_rxfhashopts(u64 opts);
+static void parse_rxntupleopts(int argc, char **argp, int first_arg);
static int dump_rxfhash(int fhash, u64 val);
static int do_srxclass(int fd, struct ifreq *ifr);
static int do_grxclass(int fd, struct ifreq *ifr);
@@ -239,12 +240,14 @@ static struct option {
" equal N | weight W0 W1 ...\n" },
{ "-U", "--config-ntuple", MODE_SNTUPLE, "Configure Rx ntuple filters "
"and actions",
- " [ flow-type tcp4|udp4|sctp4 src-ip <addr> "
- "src-ip-mask <mask> dst-ip <addr> dst-ip-mask <mask> "
- "src-port <port> src-port-mask <mask> dst-port <port> "
- "dst-port-mask <mask> vlan <VLAN tag> vlan-mask <mask> "
- "user-def <data> user-def-mask <mask> "
- "action <queue or drop>\n" },
+ " flow-type tcp4|udp4|sctp4\n"
+ " [ src-ip ADDR [src-ip-mask MASK] ]\n"
+ " [ dst-ip ADDR [dst-ip-mask MASK] ]\n"
+ " [ src-port PORT [src-port-mask MASK] ]\n"
+ " [ dst-port PORT [dst-port-mask MASK] ]\n"
+ " [ vlan VLAN-TAG [vlan-mask MASK] ]\n"
+ " [ user-def DATA [user-def-mask MASK] ]\n"
+ " action N\n" },
{ "-u", "--show-ntuple", MODE_GNTUPLE,
"Get Rx ntuple filters and actions\n" },
{ "-h", "--help", MODE_HELP, "Show this help" },
@@ -366,6 +369,18 @@ static int rxfhindir_equal = 0;
static char **rxfhindir_weight = NULL;
static int sntuple_changed = 0;
static struct ethtool_rx_ntuple_flow_spec ntuple_fs;
+static int ntuple_ip4src_seen = 0;
+static int ntuple_ip4src_mask_seen = 0;
+static int ntuple_ip4dst_seen = 0;
+static int ntuple_ip4dst_mask_seen = 0;
+static int ntuple_psrc_seen = 0;
+static int ntuple_psrc_mask_seen = 0;
+static int ntuple_pdst_seen = 0;
+static int ntuple_pdst_mask_seen = 0;
+static int ntuple_vlan_tag_seen = 0;
+static int ntuple_vlan_tag_mask_seen = 0;
+static int ntuple_user_def_seen = 0;
+static int ntuple_user_def_mask_seen = 0;
static char *flash_file = NULL;
static int flash = -1;
static int flash_region = -1;
@@ -482,18 +497,30 @@ static struct cmdline_info cmdline_coalesce[] = {
};
static struct cmdline_info cmdline_ntuple[] = {
- { "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL },
- { "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL },
- { "dst-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4dst, NULL },
- { "dst-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4dst, NULL },
- { "src-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.psrc, NULL },
- { "src-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.psrc, NULL },
- { "dst-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.pdst, NULL },
- { "dst-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.pdst, NULL },
- { "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL },
- { "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL },
- { "user-def", CMDL_U64, &ntuple_fs.data, NULL },
- { "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL },
+ { "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL,
+ 0, &ntuple_ip4src_seen },
+ { "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL,
+ 0, &ntuple_ip4src_mask_seen },
+ { "dst-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4dst, NULL,
+ 0, &ntuple_ip4dst_seen },
+ { "dst-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4dst, NULL,
+ 0, &ntuple_ip4dst_mask_seen },
+ { "src-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.psrc, NULL,
+ 0, &ntuple_psrc_seen },
+ { "src-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.psrc, NULL,
+ 0, &ntuple_psrc_mask_seen },
+ { "dst-port", CMDL_BE16, &ntuple_fs.h_u.tcp_ip4_spec.pdst, NULL,
+ 0, &ntuple_pdst_seen },
+ { "dst-port-mask", CMDL_BE16, &ntuple_fs.m_u.tcp_ip4_spec.pdst, NULL,
+ 0, &ntuple_pdst_mask_seen },
+ { "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL,
+ 0, &ntuple_vlan_tag_seen },
+ { "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL,
+ 0, &ntuple_vlan_tag_mask_seen },
+ { "user-def", CMDL_U64, &ntuple_fs.data, NULL,
+ 0, &ntuple_user_def_seen },
+ { "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL,
+ 0, &ntuple_user_def_mask_seen },
{ "action", CMDL_S32, &ntuple_fs.action, NULL },
};
@@ -844,13 +871,7 @@ static void parse_cmdline(int argc, char **argp)
show_usage(1);
break;
}
- ntuple_fs.flow_type =
- rxflow_str_to_type(argp[i]);
- i += 1;
- parse_generic_cmdline(argc, argp, i,
- &sntuple_changed,
- cmdline_ntuple,
- ARRAY_SIZE(cmdline_ntuple));
+ parse_rxntupleopts(argc, argp, i);
i = argc;
break;
} else {
@@ -1518,6 +1539,50 @@ static char *unparse_rxfhashopts(u64 opts)
return buf;
}
+static void parse_rxntupleopts(int argc, char **argp, int i)
+{
+ ntuple_fs.flow_type = rxflow_str_to_type(argp[i]);
+
+ switch (ntuple_fs.flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ parse_generic_cmdline(argc, argp, i + 1,
+ &sntuple_changed,
+ cmdline_ntuple,
+ ARRAY_SIZE(cmdline_ntuple));
+ if (!ntuple_ip4src_seen)
+ ntuple_fs.m_u.tcp_ip4_spec.ip4src = 0xffffffff;
+ if (!ntuple_ip4dst_seen)
+ ntuple_fs.m_u.tcp_ip4_spec.ip4dst = 0xffffffff;
+ if (!ntuple_psrc_seen)
+ ntuple_fs.m_u.tcp_ip4_spec.psrc = 0xffff;
+ if (!ntuple_pdst_seen)
+ ntuple_fs.m_u.tcp_ip4_spec.pdst = 0xffff;
+ ntuple_fs.m_u.tcp_ip4_spec.tos = 0xff;
+ break;
+ default:
+ fprintf(stderr, "Unsupported flow type \"%s\"\n", argp[i]);
+ exit(106);
+ break;
+ }
+
+ if (!ntuple_vlan_tag_seen)
+ ntuple_fs.vlan_tag_mask = 0xffff;
+ if (!ntuple_user_def_seen)
+ ntuple_fs.data_mask = 0xffffffffffffffffULL;
+
+ if ((ntuple_ip4src_mask_seen && !ntuple_ip4src_seen) ||
+ (ntuple_ip4dst_mask_seen && !ntuple_ip4dst_seen) ||
+ (ntuple_psrc_mask_seen && !ntuple_psrc_seen) ||
+ (ntuple_pdst_mask_seen && !ntuple_pdst_seen) ||
+ (ntuple_vlan_tag_mask_seen && !ntuple_vlan_tag_seen) ||
+ (ntuple_user_def_mask_seen && !ntuple_user_def_seen)) {
+ fprintf(stderr, "Cannot specify mask without value\n");
+ exit(107);
+ }
+}
+
static struct {
const char *name;
int (*func)(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 2/7] ethtool: Generalise cmdline_info::unwanted_val to a "seen" flag or bitmask
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 68 +++++++++++++++++++++++++++++++++---------------------------
1 files changed, 37 insertions(+), 31 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 6b2b7c8..8c5d595 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -290,7 +290,7 @@ static int off_tso_wanted = -1;
static int off_ufo_wanted = -1;
static int off_gso_wanted = -1;
static u32 off_flags_wanted = 0;
-static u32 off_flags_unwanted = 0;
+static u32 off_flags_mask = 0;
static int off_gro_wanted = -1;
static struct ethtool_pauseparam epause;
@@ -372,7 +372,7 @@ static int flash_region = -1;
static int msglvl_changed;
static u32 msglvl_wanted = 0;
-static u32 msglvl_unwanted =0;
+static u32 msglvl_mask = 0;
static enum {
ONLINE=0,
@@ -402,8 +402,10 @@ struct cmdline_info {
void *ioctl_val;
/* For FLAG, the flag value to be set/cleared */
u32 flag_val;
- /* For FLAG, accumulates all flags to be cleared */
- u32 *unwanted_val;
+ /* For FLAG, points to u32 and accumulates all flags seen.
+ * For anything else, points to int and is set if the option is
+ * seen. */
+ void *seen_val;
};
static struct cmdline_info cmdline_gregs[] = {
@@ -433,12 +435,12 @@ static struct cmdline_info cmdline_offload[] = {
{ "ufo", CMDL_BOOL, &off_ufo_wanted, NULL },
{ "gso", CMDL_BOOL, &off_gso_wanted, NULL },
{ "lro", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_LRO, &off_flags_unwanted },
+ ETH_FLAG_LRO, &off_flags_mask },
{ "gro", CMDL_BOOL, &off_gro_wanted, NULL },
{ "ntuple", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_NTUPLE, &off_flags_unwanted },
+ ETH_FLAG_NTUPLE, &off_flags_mask },
{ "rxhash", CMDL_FLAG, &off_flags_wanted, NULL,
- ETH_FLAG_RXHASH, &off_flags_unwanted },
+ ETH_FLAG_RXHASH, &off_flags_mask },
};
static struct cmdline_info cmdline_pause[] = {
@@ -497,35 +499,35 @@ static struct cmdline_info cmdline_ntuple[] = {
static struct cmdline_info cmdline_msglvl[] = {
{ "drv", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_DRV, &msglvl_unwanted },
+ NETIF_MSG_DRV, &msglvl_mask },
{ "probe", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_PROBE, &msglvl_unwanted },
+ NETIF_MSG_PROBE, &msglvl_mask },
{ "link", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_LINK, &msglvl_unwanted },
+ NETIF_MSG_LINK, &msglvl_mask },
{ "timer", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_TIMER, &msglvl_unwanted },
+ NETIF_MSG_TIMER, &msglvl_mask },
{ "ifdown", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_IFDOWN, &msglvl_unwanted },
+ NETIF_MSG_IFDOWN, &msglvl_mask },
{ "ifup", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_IFUP, &msglvl_unwanted },
+ NETIF_MSG_IFUP, &msglvl_mask },
{ "rx_err", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_RX_ERR, &msglvl_unwanted },
+ NETIF_MSG_RX_ERR, &msglvl_mask },
{ "tx_err", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_TX_ERR, &msglvl_unwanted },
+ NETIF_MSG_TX_ERR, &msglvl_mask },
{ "tx_queued", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_TX_QUEUED, &msglvl_unwanted },
+ NETIF_MSG_TX_QUEUED, &msglvl_mask },
{ "intr", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_INTR, &msglvl_unwanted },
+ NETIF_MSG_INTR, &msglvl_mask },
{ "tx_done", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_TX_DONE, &msglvl_unwanted },
+ NETIF_MSG_TX_DONE, &msglvl_mask },
{ "rx_status", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_RX_STATUS, &msglvl_unwanted },
+ NETIF_MSG_RX_STATUS, &msglvl_mask },
{ "pktdata", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_PKTDATA, &msglvl_unwanted },
+ NETIF_MSG_PKTDATA, &msglvl_mask },
{ "hw", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_HW, &msglvl_unwanted },
+ NETIF_MSG_HW, &msglvl_mask },
{ "wol", CMDL_FLAG, &msglvl_wanted, NULL,
- NETIF_MSG_WOL, &msglvl_unwanted },
+ NETIF_MSG_WOL, &msglvl_mask },
};
static long long
@@ -582,6 +584,9 @@ static void parse_generic_cmdline(int argc, char **argp,
if (!strcmp(info[idx].name, argp[i])) {
found = 1;
*changed = 1;
+ if (info[idx].type != CMDL_FLAG &&
+ info[idx].seen_val)
+ *(int *)info[idx].seen_val = 1;
i += 1;
if (i >= argc)
show_usage(1);
@@ -638,13 +643,14 @@ static void parse_generic_cmdline(int argc, char **argp,
}
case CMDL_FLAG: {
u32 *p;
- if (!strcmp(argp[i], "on"))
+ p = info[idx].seen_val;
+ *p |= info[idx].flag_val;
+ if (!strcmp(argp[i], "on")) {
p = info[idx].wanted_val;
- else if (!strcmp(argp[i], "off"))
- p = info[idx].unwanted_val;
- else
+ *p |= info[idx].flag_val;
+ } else if (strcmp(argp[i], "off")) {
show_usage(1);
- *p |= info[idx].flag_val;
+ }
break;
}
case CMDL_STR: {
@@ -1027,7 +1033,7 @@ static void parse_cmdline(int argc, char **argp)
show_usage(1);
if (isdigit((unsigned char)argp[i][0])) {
msglvl_changed = 1;
- msglvl_unwanted = ~0;
+ msglvl_mask = ~0;
msglvl_wanted =
get_uint_range(argp[i], 0,
0xffffffff);
@@ -2243,7 +2249,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
return 90;
}
}
- if (off_flags_wanted || off_flags_unwanted) {
+ if (off_flags_mask) {
changed = 1;
eval.cmd = ETHTOOL_GFLAGS;
eval.data = 0;
@@ -2255,7 +2261,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_SFLAGS;
- eval.data = ((eval.data & ~off_flags_unwanted) |
+ eval.data = ((eval.data & ~off_flags_mask) |
off_flags_wanted);
err = ioctl(fd, SIOCETHTOOL, ifr);
@@ -2459,7 +2465,7 @@ static int do_sset(int fd, struct ifreq *ifr)
perror("Cannot get msglvl");
} else {
edata.cmd = ETHTOOL_SMSGLVL;
- edata.data = ((edata.data & ~msglvl_unwanted) |
+ edata.data = ((edata.data & ~msglvl_mask) |
msglvl_wanted);
ifr->ifr_data = (caddr_t)&edata;
err = send_ioctl(fd, ifr);
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 1/7] ethtool-copy.h: sync with net-next-2.6
From: Ben Hutchings @ 2010-09-23 21:48 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
In-Reply-To: <1285278428.7794.27.camel@achroite.uk.solarflarecom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool-copy.h | 228 ++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 157 insertions(+), 71 deletions(-)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index 894f1da..1be08cf 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -14,6 +14,7 @@
#define _LINUX_ETHTOOL_H
#include <linux/types.h>
+#include <linux/if_ether.h>
/* This should work for both 32 and 64 bit userland. */
struct ethtool_cmd {
@@ -314,9 +315,20 @@ enum ethtool_flags {
};
/* The following structures are for supporting RX network flow
- * classification configuration. Note, all multibyte fields, e.g.,
- * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network
- * byte order.
+ * classification and RX n-tuple configuration. Note, all multibyte
+ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
+ * be in network byte order.
+ */
+
+/**
+ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tos: Type-of-service
+ *
+ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
*/
struct ethtool_tcpip4_spec {
__be32 ip4src;
@@ -326,6 +338,15 @@ struct ethtool_tcpip4_spec {
__u8 tos;
};
+/**
+ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @spi: Security parameters index
+ * @tos: Type-of-service
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv4.
+ */
struct ethtool_ah_espip4_spec {
__be32 ip4src;
__be32 ip4dst;
@@ -333,21 +354,17 @@ struct ethtool_ah_espip4_spec {
__u8 tos;
};
-struct ethtool_rawip4_spec {
- __be32 ip4src;
- __be32 ip4dst;
- __u8 hdata[64];
-};
-
-struct ethtool_ether_spec {
- __be16 ether_type;
- __u8 frame_size;
- __u8 eframe[16];
-};
-
#define ETH_RX_NFC_IP4 1
-#define ETH_RX_NFC_IP6 2
+/**
+ * struct ethtool_usrip4_spec - general flow specification for IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tos: Type-of-service
+ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
+ * @proto: Transport protocol number; mask must be 0
+ */
struct ethtool_usrip4_spec {
__be32 ip4src;
__be32 ip4dst;
@@ -357,6 +374,15 @@ struct ethtool_usrip4_spec {
__u8 proto;
};
+/**
+ * struct ethtool_rx_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow fields to match (dependent on @flow_type)
+ * @m_u: Masks for flow field bits to be ignored
+ * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
+ * if packets should be discarded
+ * @location: Index of filter in hardware table
+ */
struct ethtool_rx_flow_spec {
__u32 flow_type;
union {
@@ -365,36 +391,91 @@ struct ethtool_rx_flow_spec {
struct ethtool_tcpip4_spec sctp_ip4_spec;
struct ethtool_ah_espip4_spec ah_ip4_spec;
struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_rawip4_spec raw_ip4_spec;
- struct ethtool_ether_spec ether_spec;
struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[64];
- } h_u, m_u; /* entry, mask */
+ struct ethhdr ether_spec;
+ __u8 hdata[72];
+ } h_u, m_u;
__u64 ring_cookie;
__u32 location;
};
+/**
+ * struct ethtool_rxnfc - command to get or set RX flow classification rules
+ * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
+ * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
+ * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
+ * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
+ * @data: Command-dependent value
+ * @fs: Flow filter specification
+ * @rule_cnt: Number of rules to be affected
+ * @rule_locs: Array of valid rule indices
+ *
+ * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
+ * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following
+ * structure fields must not be used.
+ *
+ * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
+ * on return.
+ *
+ * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
+ * rules on return.
+ *
+ * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the index of an
+ * existing filter rule on entry and @fs contains the rule on return.
+ *
+ * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
+ * user buffer for @rule_locs on entry. On return, @data is the size
+ * of the filter table and @rule_locs contains the indices of the
+ * defined rules.
+ *
+ * For %ETHTOOL_SRXCLSRLINS, @fs specifies the filter rule to add or
+ * update. @fs.@location specifies the index to use and must not be
+ * ignored.
+ *
+ * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the index of an
+ * existing filter rule on entry.
+ *
+ * Implementation of indexed classification rules generally requires a
+ * TCAM.
+ */
struct ethtool_rxnfc {
__u32 cmd;
__u32 flow_type;
- /* The rx flow hash value or the rule DB size */
__u64 data;
- /* The following fields are not valid and must not be used for
- * the ETHTOOL_{G,X}RXFH commands. */
struct ethtool_rx_flow_spec fs;
__u32 rule_cnt;
__u32 rule_locs[0];
};
+/**
+ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
+ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
+ * @size: On entry, the array size of the user buffer. On return from
+ * %ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table.
+ * @ring_index: RX ring/queue index for each hash value
+ */
struct ethtool_rxfh_indir {
__u32 cmd;
- /* On entry, this is the array size of the user buffer. On
- * return from ETHTOOL_GRXFHINDIR, this is the array size of
- * the hardware indirection table. */
__u32 size;
- __u32 ring_index[0]; /* ring/queue index for each hash value */
+ __u32 ring_index[0];
};
+/**
+ * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow field values to match (dependent on @flow_type)
+ * @m_u: Masks for flow field value bits to be ignored
+ * @vlan_tag: VLAN tag to match
+ * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
+ * @data: Driver-dependent data to match
+ * @data_mask: Mask for driver-dependent data bits to be ignored
+ * @action: RX ring/queue index to deliver to (non-negative) or other action
+ * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
+ *
+ * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
+ * a field value and mask are both zero this is treated as if all mask
+ * bits are set i.e. the field is ignored.
+ */
struct ethtool_rx_ntuple_flow_spec {
__u32 flow_type;
union {
@@ -403,22 +484,26 @@ struct ethtool_rx_ntuple_flow_spec {
struct ethtool_tcpip4_spec sctp_ip4_spec;
struct ethtool_ah_espip4_spec ah_ip4_spec;
struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_rawip4_spec raw_ip4_spec;
- struct ethtool_ether_spec ether_spec;
struct ethtool_usrip4_spec usr_ip4_spec;
- __u8 hdata[64];
- } h_u, m_u; /* entry, mask */
+ struct ethhdr ether_spec;
+ __u8 hdata[72];
+ } h_u, m_u;
__u16 vlan_tag;
__u16 vlan_tag_mask;
- __u64 data; /* user-defined flow spec data */
- __u64 data_mask; /* user-defined flow spec mask */
+ __u64 data;
+ __u64 data_mask;
- /* signed to distinguish between queue and actions (DROP) */
__s32 action;
-#define ETHTOOL_RXNTUPLE_ACTION_DROP -1
+#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */
};
+/**
+ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
+ * @cmd: Command number - %ETHTOOL_SRXNTUPLE
+ * @fs: Flow filter specification
+ */
struct ethtool_rx_ntuple {
__u32 cmd;
struct ethtool_rx_ntuple_flow_spec fs;
@@ -444,29 +529,29 @@ struct ethtool_flash {
#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers. */
#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */
-#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
-#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */
+#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */
#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */
#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
-#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
-#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */
+#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
+#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */
#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters. */
#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
-#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
-#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
-#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
-#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
+#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
+#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
+#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
+#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
* (ethtool_value) */
#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
* (ethtool_value). */
#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test. */
#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
-#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
+#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
@@ -477,8 +562,8 @@ struct ethtool_flash {
#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */
#define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */
#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */
-#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
-#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
+#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
+#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */
#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */
@@ -505,18 +590,18 @@ struct ethtool_flash {
/* Indicates what features are supported by the interface. */
#define SUPPORTED_10baseT_Half (1 << 0)
#define SUPPORTED_10baseT_Full (1 << 1)
-#define SUPPORTED_100baseT_Half (1 << 2)
-#define SUPPORTED_100baseT_Full (1 << 3)
+#define SUPPORTED_100baseT_Half (1 << 2)
+#define SUPPORTED_100baseT_Full (1 << 3)
#define SUPPORTED_1000baseT_Half (1 << 4)
#define SUPPORTED_1000baseT_Full (1 << 5)
#define SUPPORTED_Autoneg (1 << 6)
#define SUPPORTED_TP (1 << 7)
#define SUPPORTED_AUI (1 << 8)
#define SUPPORTED_MII (1 << 9)
-#define SUPPORTED_FIBRE (1 << 10)
+#define SUPPORTED_FIBRE (1 << 10)
#define SUPPORTED_BNC (1 << 11)
#define SUPPORTED_10000baseT_Full (1 << 12)
-#define SUPPORTED_Pause (1 << 13)
+#define SUPPORTED_Pause (1 << 13)
#define SUPPORTED_Asym_Pause (1 << 14)
#define SUPPORTED_2500baseX_Full (1 << 15)
#define SUPPORTED_Backplane (1 << 16)
@@ -526,8 +611,8 @@ struct ethtool_flash {
#define SUPPORTED_10000baseR_FEC (1 << 20)
/* Indicates what features are advertised by the interface. */
-#define ADVERTISED_10baseT_Half (1 << 0)
-#define ADVERTISED_10baseT_Full (1 << 1)
+#define ADVERTISED_10baseT_Half (1 << 0)
+#define ADVERTISED_10baseT_Full (1 << 1)
#define ADVERTISED_100baseT_Half (1 << 2)
#define ADVERTISED_100baseT_Full (1 << 3)
#define ADVERTISED_1000baseT_Half (1 << 4)
@@ -566,12 +651,12 @@ struct ethtool_flash {
#define DUPLEX_FULL 0x01
/* Which connector port. */
-#define PORT_TP 0x00
+#define PORT_TP 0x00
#define PORT_AUI 0x01
#define PORT_MII 0x02
#define PORT_FIBRE 0x03
#define PORT_BNC 0x04
-#define PORT_DA 0x05
+#define PORT_DA 0x05
#define PORT_NONE 0xef
#define PORT_OTHER 0xff
@@ -585,7 +670,7 @@ struct ethtool_flash {
/* Enable or disable autonegotiation. If this is set to enable,
* the forced link modes above are completely ignored.
*/
-#define AUTONEG_DISABLE 0x00
+#define AUTONEG_DISABLE 0x00
#define AUTONEG_ENABLE 0x01
/* Mode MDI or MDI-X */
@@ -602,22 +687,23 @@ struct ethtool_flash {
#define WAKE_MAGIC (1 << 5)
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
-/* L3-L4 network traffic flow types */
-#define TCP_V4_FLOW 0x01
-#define UDP_V4_FLOW 0x02
-#define SCTP_V4_FLOW 0x03
-#define AH_ESP_V4_FLOW 0x04
-#define TCP_V6_FLOW 0x05
-#define UDP_V6_FLOW 0x06
-#define SCTP_V6_FLOW 0x07
-#define AH_ESP_V6_FLOW 0x08
-#define AH_V4_FLOW 0x09
-#define ESP_V4_FLOW 0x0a
-#define AH_V6_FLOW 0x0b
-#define ESP_V6_FLOW 0x0c
-#define IP_USER_FLOW 0x0d
-#define IPV4_FLOW 0x10
-#define IPV6_FLOW 0x11
+/* L2-L4 network traffic flow types */
+#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
+#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
+#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */
+#define AH_ESP_V4_FLOW 0x04 /* hash only */
+#define TCP_V6_FLOW 0x05 /* hash only */
+#define UDP_V6_FLOW 0x06 /* hash only */
+#define SCTP_V6_FLOW 0x07 /* hash only */
+#define AH_ESP_V6_FLOW 0x08 /* hash only */
+#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */
+#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */
+#define AH_V6_FLOW 0x0b /* hash only */
+#define ESP_V6_FLOW 0x0c /* hash only */
+#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */
+#define IPV4_FLOW 0x10 /* hash only */
+#define IPV6_FLOW 0x11 /* hash only */
+#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
/* L3-L4 network traffic flow hash options */
#define RXH_L2DA (1 << 1)
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 0/7] Update RX n-tuple filtering
From: Ben Hutchings @ 2010-09-23 21:47 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-net-drivers
This patch series brings ethtool up to date with my recent changes to RX
n-tuple filtering in the kernel.
Ben.
Ben Hutchings (7):
ethtool-copy.h: sync with net-next
ethtool: Generalise cmdline_info::unwanted_val to a "seen" flag or
bitmask
ethtool: Fix RX n-tuple masks and documentation
ethtool: Add MAC parameter type based on the parse_sopass() function
ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action
ethtool: Update sfc register dump
ethtool: Add my authorship and Solarflare copyright notice
AUTHORS | 1 +
ethtool-copy.h | 228 +++++++++++++++++++++++++++++++++---------------
ethtool.8 | 79 ++++++++++++-----
ethtool.c | 265 +++++++++++++++++++++++++++++++++++++++++---------------
sfc.c | 25 +++---
5 files changed, 426 insertions(+), 172 deletions(-)
--
1.7.2.1
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH v6 0/8] ptp: IEEE 1588 hardware clock support
From: john stultz @ 2010-09-23 21:42 UTC (permalink / raw)
To: Christoph Lameter
Cc: Richard Cochran, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
netdev-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, David Miller,
Krzysztof Halasa, Peter Zijlstra, Rodolfo Giometti,
Thomas Gleixner
In-Reply-To: <alpine.DEB.2.00.1009231533040.7522-sBS69tsa9Uj/9pzu0YdTqQ@public.gmane.org>
On Thu, 2010-09-23 at 15:49 -0500, Christoph Lameter wrote:
> On Thu, 23 Sep 2010, john stultz wrote:
>
> > > The HPET or pit timesource are also quite slow these days. You only need
> > > access periodically to essentially tune the TSC ratio.
> >
> > If we're using the TSC, then we're not using the PTP clock as you
> > suggest. Further the HPET and PIT aren't used to steer the system time
> > when we are using the TSC as a clocksource. Its only used to calibrate
> > the initial constant freq used by the timekeeping code (and if its
> > non-constant, we throw it out).
>
> There is no other scalable time source available for fast timer access
> than the time stamp counter in the cpu. Other time source require
> memory accesses which is inherently slower.
Right, but no one likes the HPET or ACPI PM for a clocksource, its just
the TSC isn't usable in some cases, so they have to be used.
We don't want to force folks to decide between closely sycned time and
fast time reads. So that is part of the reason why PTP as a clocksource
isn't a good idea.
> An accurate other time source is used to adjust this clock. NTP does that
> via the clock interfaces from user space which has its problems with
> accuracy. PTP can provide the network synced time access
> that would a more accurate calibration of the time.
Calibration isn't whats needed here (it is an issue, but a separate one
- and I've got some patches if you're interested!) as its a one-time
source of error and can be corrected by ntp today without trouble.
Adjustments to the system time is something that has to be done
continuously to handle for variable thermal drift over time.
> > 2) The way PTP clocks are steered to sync with network time causes their
> > hardware freq to actually change. Since these adjustments are done on
> > the hardware clock level, and not on the system time level, the
> > adjustments to sync the system time/freq would then be made incorrect by
> > PTP hardware adjustments.
>
> Right. So use these as a way to fine tune the TSC clock (and thereby the
> system time).
So you're then not suggesting to "use the PTP as a clocksource".
Using the PTP hardware to adjust the system time freq is exactly whats
being proposed.
> > 3) Further, the PTP hardware counter can be simply set to a new offset
> > to put it in line with the network time. This could cause trouble with
> > timekeeping much like unsynced TSCs do.
>
> You can do the same for system time.
Settimeofday does allow CLOCK_REALTIME to jump, but the CLOCK_MONOTONIC
time cannot jump around. Having a clocksource that is non-monotonic
would break this.
> > Now, what you seem to be suggesting is to use the TSC (or whatever
> > clocksource the system time is using) but to steer the system time using
> > the PTP clock. This is actually what is being proposed, however, the
> > steering is done in userland. This is due to the fact that there are two
> > components to the steering, 1) adjusting the PTP clock hardware to
> > network time and 2) adjusting the system time to the PTP hardware. By
> > exposing the PTP clock to userland via the posix clocks interface, we
> > allow this to easily be done.
>
> Userland code would introduce latencies that would make sub microsecond
> time sync very difficult.
The design actually avoids most userland induced latency.
1) On the PTP hardware syncing point, the reference packet gets
timestamped with the PTP hardware time on arrival. This allows the
offset calculation to be done in userland without introducing latency.
2) On the system syncing side, the proposal for the PPS interrupt allows
the PTP hardware to trigger an interrupt on the second boundary that
would take a timestamp of the system time. Then the pps interface allows
for the timestamp to be read from userland allowing the offset to be
calculated without introducing additional latency.
> > > We can switch underlying clocks for system time already. We can adapt to a
> > > different hw frequency.
> >
> > Actually no. The timekeeping code requires a fixed freq counter. Dealing
> > with hardware freq changes is difficult, because error is introduced by
> > the latency between when the freq changes and when the timekeeping code
> > is notified of it. So the system treats the hardware counters as fixed
> > freq. Now, hardware does vary freq ever so slightly as thermal
> > conditions change, but this is addressed in userland and corrected via
> > adjtimex.
>
> Acadmic hair splitting? I have repeatedly switched between different
> clocks on various systems. So its difficult but we do it?
Sure, we handle the fairly-rare case of switching clocksources. And that
introduces a bit of error each time. But one doesn't expect to be
switching clock-sources every second and still keep synced time.
> > Unnecessary layers? Where? This approach has less in-kernel layers, as
> > it exposes the PTP clock to userland, instead of trying to layer things
> > on top of it and stretching the system time abstraction to cover it.
>
> You dont need the user APIs if you directly use the PTP time source to
> steer the system clock. In fact I think you have to do it in kernel space
> since user space latencies will degrade accuracy otherwise.
Via the PPS interface, this can be done easily without large latency.
Additionally, even just in userland, it would be easy to bracket two
reads of the system time around one read of the PTP clock to bound any
userland latency fairly well. It may not be as good as the PPS interface
(although that depends on the interrupt latency), but if the accesses
are all local, it probably could get fairly close.
> > I've argued through the approach trying to keep it all internal to the
> > kernel, but to do so would be anything but trivial. Further, there's the
> > case of master-clocks, where the PTP hardware must be synced to system
> > time, instead of the other way around. And then there's the case of
> > boundary-clocks, which may have multiple PTP hardware clocks that have
> > to be synced.
>
> Ok maybe we need some sort of control interface to manage the clock like
> the others have.
That's what the clock_adjtime call provides.
> > I think exposing this through the posix clock interface is really the
> > best approach. Its not a static clockid, so its not something most apps
> > will ever have to deal with, but it allows the few apps that really need
> > to have access to the PTP clock hardware can do so in a clean way.
>
> It implies clock tuning in userspace for a potential sub microsecond
> accurate clock. The clock accuracy will be limited by user space
> latencies and noise. You wont be able to discipline the system clock
> accurately.
I think you'll find that the userspace latency issue is fairly well
addressed by the existing design.
> The posix clocks today assumes one notion of real "time" in the kernel.
> All clocks increase in lockstep (aside from offset updates).
Not true. The cputime clockids do not increment at the same rate (as the
apps don't always run). Further CLOCK_MONOTONIC_RAW provides a non-freq
corrected view of CLOCK_MONOTONIC, so it increments at a slightly
different rate.
> This approach
> here result in multiple notions of "time" increasing at various speeds.
Yes. I found this initially to be distasteful as well. But the more I
realized its just a reality of the hardware, and that as long as its not
advertised along side of CLOCK_REALTIME and CLOCK_MONOTONIC (the ptp
clock ids are dynamic and somewhat hidden in the sysfs tree), so
userland developers don't get confused, its not so bad.
Especially since driver writers will just expose the same stuff via a
chardev ioctl in a less standard way and its likely no one will notice.
Re-using the fairly nice (Alan of course disagrees :) posix interface
seems at least a little better for application developers who actually
have to use the hardware.
thanks
-john
^ permalink raw reply
* [PATCH v3] xmit_compl_seq: information to reclaim vmsplice buffers
From: Tom Herbert @ 2010-09-23 21:35 UTC (permalink / raw)
To: netdev, davem; +Cc: sridharr
In this patch we propose to adds some socket API to retrieve the
"transmit completion sequence number", essentially a byte counter
for the number of bytes that have been transmitted and will not be
retransmitted. In the case of TCP, this should correspond to snd_una.
The purpose of this API is to provide information to userspace about
which buffers can be reclaimed when sending with vmsplice() on a
socket.
There are two methods for retrieving the completed sequence number:
through a simple getsockopt (implemented here for TCP), as well as
returning the value in the ancilary data of a recvmsg.
The expected flow would be something like:
- Connect is created
- Initial completion seq # is retrieved through the sockopt, and is
stored in userspace "compl_seq" variable for the connection.
- Whenever a send is done, compl_seq += # bytes sent.
- When doing a vmsplice the completion sequence number is saved
for each user space buffer, buffer_compl_seq = compl_seq.
- When recvmsg returns with a completion sequence number in
ancillary data, any buffers cover by that sequence number
(where buffer_compl_seq < recvmsg_compl_seq) are reclaimed
and can be written to again.
- If no data is receieved on a connection (recvmsg does not
return), a timeout can be used to call the getsockopt and
reclaim buffers as a fallback.
Using recvmsg data in this manner is sort of a cheap way to get a
"callback" for when a vmspliced buffer is consumed. It will work
well for a client where the response causes recvmsg to return.
On the server side it works well if there are a sufficient
number of requests coming on the connection (resorting to the
timeout if necessary as described above).
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: Sridhar Raman <sridharr@google.com>
---
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 06edfef..3587082 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -69,6 +69,9 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
+
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
*/
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index 90ffd04..962c365 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index c8d1fae..de59dfe 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index 1a4a619..fe9a1ba 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -64,6 +64,8 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index a6b2688..769f1f5 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -62,5 +62,7 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index 04c0f45..5ef4551 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index 51427ea..217e4d8 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -71,4 +71,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index 469787c..e0830c6 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index 9bf49c8..438cb8e 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index 9de5190..cb927d7 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -82,6 +82,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
+
#ifdef __KERNEL__
/** sock_type - Socket types
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index 4e60c42..1c09487 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -62,4 +62,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index 225b7d6..c1b0479 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -61,6 +61,9 @@
#define SO_RXQ_OVFL 0x4021
+#define SO_XMIT_COMPL_SEQ 0x4022
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
+
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
*/
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index 866f760..9452547 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -69,4 +69,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index fdff1e9..3e3c17b 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -70,4 +70,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _ASM_SOCKET_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 9d3fefc..0675f54 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -58,6 +58,9 @@
#define SO_RXQ_OVFL 0x0024
+#define SO_XMIT_COMPL_SEQ 0x0025
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index cbdf2ff..3c5afbf 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -73,4 +73,6 @@
#define SO_RXQ_OVFL 40
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* _XTENSA_SOCKET_H */
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index 9a6115e..6dc1ed8 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -64,4 +64,7 @@
#define SO_DOMAIN 39
#define SO_RXQ_OVFL 40
+
+#define SO_XMIT_COMPL_SEQ 41
+#define SCM_XMIT_COMPL_SEQ SO_XMIT_COMPL_SEQ
#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index e64f4c6..f044aff 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -106,6 +106,7 @@ enum {
#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
+#define TCP_XMIT_COMPL_SEQ 19 /* Return current snd_una */
/* for TCP_INFO socket option */
#define TCPI_OPT_TIMESTAMPS 1
diff --git a/include/net/sock.h b/include/net/sock.h
index 8ae97c4..e820e2b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -543,6 +543,7 @@ enum sock_flags {
SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */
SOCK_FASYNC, /* fasync() active */
SOCK_RXQ_OVFL,
+ SOCK_XMIT_COMPL_SEQ, /* SO_XMIT_COMPL_SEQ setting */
};
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
diff --git a/net/core/sock.c b/net/core/sock.c
index f3a06c4..7a10215 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -740,6 +740,12 @@ set_rcvbuf:
else
sock_reset_flag(sk, SOCK_RXQ_OVFL);
break;
+ case SO_XMIT_COMPL_SEQ:
+ if (valbool)
+ sock_set_flag(sk, SOCK_XMIT_COMPL_SEQ);
+ else
+ sock_reset_flag(sk, SOCK_XMIT_COMPL_SEQ);
+ break;
default:
ret = -ENOPROTOOPT;
break;
@@ -961,6 +967,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = !!sock_flag(sk, SOCK_RXQ_OVFL);
break;
+ case SO_XMIT_COMPL_SEQ:
+ v.val = !!sock_flag(sk, SOCK_XMIT_COMPL_SEQ);
+ break;
+
default:
return -ENOPROTOOPT;
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 3e8a4db..3d8d33f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1768,6 +1768,12 @@ skip_copy:
TCP_CHECK_TIMER(sk);
release_sock(sk);
+
+ /* Copy the first unacked seq into the receive msg control part. */
+ if (sock_flag(sk, SOCK_XMIT_COMPL_SEQ))
+ put_cmsg(msg, SOL_SOCKET, SCM_XMIT_COMPL_SEQ,
+ sizeof(tp->snd_una), &tp->snd_una);
+
return copied;
out:
@@ -2617,6 +2623,9 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
case TCP_USER_TIMEOUT:
val = jiffies_to_msecs(icsk->icsk_user_timeout);
break;
+ case TCP_XMIT_COMPL_SEQ:
+ val = tp->snd_una;
+ break;
default:
return -ENOPROTOOPT;
}
^ permalink raw reply related
* Re: [PATCH net-next-2.6] net: return operator cleanup
From: David Miller @ 2010-09-23 21:34 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1285224237.2380.111.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 23 Sep 2010 08:43:57 +0200
> Change "return (EXPR);" to "return EXPR;"
>
> return is not a function, parentheses are not required.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH v6 0/8] ptp: IEEE 1588 hardware clock support
From: Alan Cox @ 2010-09-23 21:34 UTC (permalink / raw)
To: Christoph Lameter
Cc: john stultz, Richard Cochran, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
netdev-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, David Miller,
Krzysztof Halasa, Peter Zijlstra, Rodolfo Giometti,
Thomas Gleixner
In-Reply-To: <alpine.DEB.2.00.1009231533040.7522-sBS69tsa9Uj/9pzu0YdTqQ@public.gmane.org>
> There is no other scalable time source available for fast timer access
> than the time stamp counter in the cpu. Other time source require
> memory accesses which is inherently slower.
On what hardware ?
> An accurate other time source is used to adjust this clock. NTP does that
> via the clock interfaces from user space which has its problems with
> accuracy. PTP can provide the network synced time access
> that would a more accurate calibration of the time.
Accuracy does not require speed of access. Accuracy requires predictible
latency of access.
> Userland code would introduce latencies that would make sub microsecond
> time sync very difficult.
You can take a multiple micro-second I/O stall or SMI trap on a PC so you
already lost the battle on the platform you seem to be discussing.
> You dont need the user APIs if you directly use the PTP time source to
> steer the system clock. In fact I think you have to do it in kernel space
> since user space latencies will degrade accuracy otherwise.
PTP is not a 'time source' it is one or more source of time. The
distinction is rather important.
> It implies clock tuning in userspace for a potential sub microsecond
> accurate clock. The clock accuracy will be limited by user space
> latencies and noise. You wont be able to discipline the system clock
> accurately.
Noise matters, latency doesn't. And the kernel is getting more and more
real time support all the time.
^ permalink raw reply
* Re: [net-next-2.6 PATCH 3/3] e1000: use GRO for receive
From: David Miller @ 2010-09-23 21:34 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, gospo, bphilips, jesse.brandeburg
In-Reply-To: <20100923042303.11798.50335.stgit@localhost.localdomain>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 22 Sep 2010 21:23:05 -0700
> From: Jesse Brandeburg <jesse.brandeburg@intel.com>
>
> E1000 can benefit from calling the GRO receive functions.
>
> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Applied.
^ permalink raw reply
* Re: [PATCH v6 0/8] ptp: IEEE 1588 hardware clock support
From: Christian Riesch @ 2010-09-23 21:34 UTC (permalink / raw)
To: Alan Cox
Cc: Christoph Lameter, john stultz, Richard Cochran, linux-kernel,
devicetree-discuss, linux-api, linux-arm-kernel, linuxppc-dev,
netdev, Arnd Bergmann, David Miller, Krzysztof Halasa,
Peter Zijlstra, Rodolfo Giometti, Thomas Gleixner
In-Reply-To: <20100923223417.4ed62e5b@lxorguk.ukuu.org.uk>
Alan Cox wrote:
>> It implies clock tuning in userspace for a potential sub microsecond
>> accurate clock. The clock accuracy will be limited by user space
>> latencies and noise. You wont be able to discipline the system clock
>> accurately.
>
> Noise matters, latency doesn't.
Well put! That's why we need hardware support for PTP timestamping to
reduce the noise, but get along well with the clock servo that is
steering the PHC in user space.
Christian
^ permalink raw reply
* Re: [net-next-2.6 PATCH 2/3] e1000: fix occasional panic on unload
From: David Miller @ 2010-09-23 21:34 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, gospo, bphilips, jesse.brandeburg
In-Reply-To: <20100923042240.11798.65680.stgit@localhost.localdomain>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 22 Sep 2010 21:22:42 -0700
> From: Jesse Brandeburg <jesse.brandeburg@intel.com>
>
> Net drivers in general have an issue where timers fired
> by mod_timer or work threads with schedule_work are running
> outside of the rtnl_lock.
>
> With no other lock protection these routines are vulnerable
> to races with driver unload or reset paths.
>
> The longer term solution to this might be a redesign with
> safer locks being taken in the driver to guarantee no
> reentrance, but for now a safe and effective fix is
> to take the rtnl_lock in these routines.
>
> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Applied.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox