* [PATCH net-next 0/9] s390/net: updates 2019-08-20
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
Hi Dave,
please apply the following patches to net-next. This series brings a mix
of cleanups and small improvements for various parts of qeth's control
path. Also, a minor cleanup for ctcm and lcs.
Thanks,
Julian
Julian Wiedmann (9):
s390/qeth: use node_descriptor struct
s390/qeth: propagate length of processed cmd IO data to callback
s390/qeth: use correct length field in SNMP cmd callback
s390/qeth: keep cmd alive after IO completion
s390/qeth: merge qeth_reply struct into qeth_cmd_buffer
s390/qeth: get vnicc sub-cmd type from reply data
s390/qeth: streamline control code for promisc mode
s390/ctcm: don't use intparm for channel IO
s390/lcs: don't use intparm for channel IO
drivers/s390/net/ctcm_fsms.c | 42 ++---
drivers/s390/net/ctcm_main.c | 6 +-
drivers/s390/net/ctcm_mpc.c | 6 +-
drivers/s390/net/lcs.c | 6 +-
drivers/s390/net/qeth_core.h | 36 ++---
drivers/s390/net/qeth_core_main.c | 261 ++++++++++++++----------------
drivers/s390/net/qeth_core_mpc.h | 1 -
drivers/s390/net/qeth_l2_main.c | 62 +++----
drivers/s390/net/qeth_l3_main.c | 24 +--
9 files changed, 197 insertions(+), 247 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH net-next 4/9] s390/qeth: keep cmd alive after IO completion
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
Current code releases the cmd struct after its initial IO has completed.
Any reply processing is done independently, using a separate qeth_reply
struct.
In preparation for merging the cmd and reply structs together, take an
additional reference on the cmd object so that it stays around all the
way until qeth_send_control_data() returns.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core_main.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 49e85d2e79c2..3fc14f222dc3 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1742,6 +1742,9 @@ static int qeth_send_control_data(struct qeth_card *card,
qeth_enqueue_reply(card, reply);
+ /* This pairs with iob->callback, and keeps the iob alive after IO: */
+ qeth_get_cmd(iob);
+
QETH_CARD_TEXT(card, 6, "noirqpnd");
spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, __ccw_from_cmd(iob),
@@ -1752,11 +1755,10 @@ static int qeth_send_control_data(struct qeth_card *card,
CARD_DEVID(card), rc);
QETH_CARD_TEXT_(card, 2, " err%d", rc);
qeth_dequeue_reply(card, reply);
- qeth_put_reply(reply);
qeth_put_cmd(iob);
atomic_set(&channel->irq_pending, 0);
wake_up(&card->wait_q);
- return rc;
+ goto out;
}
timeout = wait_for_completion_interruptible_timeout(&reply->received,
@@ -1777,7 +1779,10 @@ static int qeth_send_control_data(struct qeth_card *card,
if (!rc)
rc = reply->rc;
+
+out:
qeth_put_reply(reply);
+ qeth_put_cmd(iob);
return rc;
}
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 3/9] s390/qeth: use correct length field in SNMP cmd callback
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
qeth_snmp_command_cb() is the only cmd callback that pulls the reply's
data length from a low-level transport header field. This requires
additional complexity (ie. reply->offset) to make the header accessible
to what is supposed to be a pure IPA cmd callback.
Adapter cmds have a length field in their sub-cmd header, get the data
length from there instead.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core.h | 1 -
drivers/s390/net/qeth_core_main.c | 42 ++++++++++++-------------------
2 files changed, 16 insertions(+), 27 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 4e21aa8edb13..f6e58a51c366 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -634,7 +634,6 @@ struct qeth_reply {
int (*callback)(struct qeth_card *, struct qeth_reply *,
unsigned long);
u32 seqno;
- unsigned long offset;
int rc;
void *param;
refcount_t refcnt;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index f7a8b8301eb4..49e85d2e79c2 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -807,17 +807,12 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
}
spin_lock_irqsave(&reply->lock, flags);
- if (reply->rc) {
+ if (reply->rc)
/* Bail out when the requestor has already left: */
rc = reply->rc;
- } else {
- if (cmd) {
- reply->offset = (u16)((char *)cmd - (char *)iob->data);
- rc = reply->callback(card, reply, (unsigned long)cmd);
- } else {
- rc = reply->callback(card, reply, (unsigned long)iob);
- }
- }
+ else
+ rc = reply->callback(card, reply, cmd ? (unsigned long)cmd :
+ (unsigned long)iob);
spin_unlock_irqrestore(&reply->lock, flags);
no_callback:
@@ -4335,20 +4330,16 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
}
static int qeth_snmp_command_cb(struct qeth_card *card,
- struct qeth_reply *reply, unsigned long sdata)
+ struct qeth_reply *reply, unsigned long data)
{
- struct qeth_ipa_cmd *cmd;
- struct qeth_arp_query_info *qinfo;
- unsigned char *data;
+ struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
+ struct qeth_arp_query_info *qinfo = reply->param;
+ struct qeth_ipacmd_setadpparms *adp_cmd;
+ unsigned int data_len;
void *snmp_data;
- __u16 data_len;
QETH_CARD_TEXT(card, 3, "snpcmdcb");
- cmd = (struct qeth_ipa_cmd *) sdata;
- data = (unsigned char *)((char *)cmd - reply->offset);
- qinfo = (struct qeth_arp_query_info *) reply->param;
-
if (cmd->hdr.return_code) {
QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code);
return -EIO;
@@ -4359,15 +4350,14 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
QETH_CARD_TEXT_(card, 4, "scer2%x", cmd->hdr.return_code);
return -EIO;
}
- data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
- if (cmd->data.setadapterparms.hdr.seq_no == 1) {
- snmp_data = &cmd->data.setadapterparms.data.snmp;
- data_len -= offsetof(struct qeth_ipa_cmd,
- data.setadapterparms.data.snmp);
+
+ adp_cmd = &cmd->data.setadapterparms;
+ data_len = adp_cmd->hdr.cmdlength - sizeof(adp_cmd->hdr);
+ if (adp_cmd->hdr.seq_no == 1) {
+ snmp_data = &adp_cmd->data.snmp;
} else {
- snmp_data = &cmd->data.setadapterparms.data.snmp.request;
- data_len -= offsetof(struct qeth_ipa_cmd,
- data.setadapterparms.data.snmp.request);
+ snmp_data = &adp_cmd->data.snmp.request;
+ data_len -= offsetof(struct qeth_snmp_cmd, request);
}
/* check if there is enough room in userspace */
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 6/9] s390/qeth: get vnicc sub-cmd type from reply data
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
When processing the reply for a vnicc cmd, there's no need to remember
which specific sub-cmd type we initially sent. The reply itself contains
all the needed information.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_l2_main.c | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index ad7ee3bfd63c..1f534f489a79 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1704,7 +1704,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc)
/* generic VNICC request call back control */
struct _qeth_l2_vnicc_request_cbctl {
- u32 sub_cmd;
struct {
union{
u32 *sup_cmds;
@@ -1722,6 +1721,7 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
(struct _qeth_l2_vnicc_request_cbctl *) reply->param;
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct qeth_ipacmd_vnicc *rep = &cmd->data.vnicc;
+ u32 sub_cmd = cmd->data.vnicc.hdr.sub_command;
QETH_CARD_TEXT(card, 2, "vniccrcb");
if (cmd->hdr.return_code)
@@ -1730,10 +1730,9 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
card->options.vnicc.sup_chars = rep->vnicc_cmds.supported;
card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled;
- if (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS)
+ if (sub_cmd == IPA_VNICC_QUERY_CMDS)
*cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds;
-
- if (cbctl->sub_cmd == IPA_VNICC_GET_TIMEOUT)
+ else if (sub_cmd == IPA_VNICC_GET_TIMEOUT)
*cbctl->result.timeout = rep->data.getset_timeout.timeout;
return 0;
@@ -1761,7 +1760,6 @@ static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card,
/* VNICC query VNIC characteristics request */
static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
{
- struct _qeth_l2_vnicc_request_cbctl cbctl;
struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "vniccqch");
@@ -1769,10 +1767,7 @@ static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
if (!iob)
return -ENOMEM;
- /* prepare callback control */
- cbctl.sub_cmd = IPA_VNICC_QUERY_CHARS;
-
- return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
+ return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, NULL);
}
/* VNICC query sub commands request */
@@ -1791,7 +1786,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
__ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char;
/* prepare callback control */
- cbctl.sub_cmd = IPA_VNICC_QUERY_CMDS;
cbctl.result.sup_cmds = sup_cmds;
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
@@ -1801,7 +1795,6 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
u32 cmd)
{
- struct _qeth_l2_vnicc_request_cbctl cbctl;
struct qeth_cmd_buffer *iob;
QETH_CARD_TEXT(card, 2, "vniccedc");
@@ -1811,10 +1804,7 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
__ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char;
- /* prepare callback control */
- cbctl.sub_cmd = cmd;
-
- return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
+ return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, NULL);
}
/* VNICC get/set timeout for characteristic request */
@@ -1838,7 +1828,6 @@ static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc,
getset_timeout->timeout = *timeout;
/* prepare callback control */
- cbctl.sub_cmd = cmd;
if (cmd == IPA_VNICC_GET_TIMEOUT)
cbctl.result.timeout = timeout;
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 8/9] s390/ctcm: don't use intparm for channel IO
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
ctcm passes an intparm when calling ccw_device_*(), even though
ctcm_irq_handler() later makes no use of this.
To reduce the confusion, consistently pass 0 as intparm instead.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Sebastian Ott <sebott@linux.ibm.com>
---
drivers/s390/net/ctcm_fsms.c | 42 ++++++++++++++----------------------
drivers/s390/net/ctcm_main.c | 6 ++----
drivers/s390/net/ctcm_mpc.c | 6 ++----
3 files changed, 20 insertions(+), 34 deletions(-)
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index 4a8a5373cb35..3ce99e4db44d 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -307,8 +307,7 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
ch->ccw[1].count = ch->trans_skb->len;
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
ch->prof.send_stamp = jiffies;
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
ch->prof.doios_multi++;
if (rc != 0) {
priv->stats.tx_dropped += i;
@@ -417,8 +416,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
if (ctcm_checkalloc_buffer(ch))
return;
ch->ccw[1].count = ch->max_bufsize;
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
if (rc != 0)
ctcm_ccw_check_rc(ch, rc, "normal RX");
}
@@ -478,8 +476,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == CTCM_READ)
? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
if (rc != 0) {
fsm_deltimer(&ch->timer);
fsm_newstate(fi, CTC_STATE_SETUPWAIT);
@@ -527,8 +524,7 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
return;
ch->ccw[1].count = ch->max_bufsize;
fsm_newstate(fi, CTC_STATE_RXIDLE);
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
if (rc != 0) {
fsm_newstate(fi, CTC_STATE_RXINIT);
ctcm_ccw_check_rc(ch, rc, "initial RX");
@@ -571,8 +567,7 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
/* Such conditional locking is undeterministic in
* static view. => ignore sparse warnings here. */
- rc = ccw_device_start(ch->cdev, &ch->ccw[6],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[6], 0, 0xff, 0);
if (event == CTC_EVENT_TIMER) /* see above comments */
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) {
@@ -637,7 +632,7 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, CTC_STATE_STARTWAIT);
fsm_addtimer(&ch->timer, 1000, CTC_EVENT_TIMER, ch);
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
- rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
+ rc = ccw_device_halt(ch->cdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) {
if (rc != -EBUSY)
@@ -672,7 +667,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
* static view. => ignore sparse warnings here. */
oldstate = fsm_getstate(fi);
fsm_newstate(fi, CTC_STATE_TERM);
- rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
+ rc = ccw_device_halt(ch->cdev, 0);
if (event == CTC_EVENT_STOP)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
@@ -799,7 +794,7 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
if (!IS_MPC(ch) &&
(CHANNEL_DIRECTION(ch->flags) == CTCM_READ)) {
- int rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
+ int rc = ccw_device_halt(ch->cdev, 0);
if (rc != 0)
ctcm_ccw_check_rc(ch, rc,
"HaltIO in chx_setuperr");
@@ -851,7 +846,7 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)
/* Such conditional locking is a known problem for
* sparse because its undeterministic in static view.
* Warnings should be ignored here. */
- rc = ccw_device_halt(ch->cdev, (unsigned long)ch);
+ rc = ccw_device_halt(ch->cdev, 0);
if (event == CTC_EVENT_TIMER)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) {
@@ -947,8 +942,8 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
ch2 = priv->channel[CTCM_WRITE];
fsm_newstate(ch2->fsm, CTC_STATE_DTERM);
- ccw_device_halt(ch->cdev, (unsigned long)ch);
- ccw_device_halt(ch2->cdev, (unsigned long)ch2);
+ ccw_device_halt(ch->cdev, 0);
+ ccw_device_halt(ch2->cdev, 0);
}
/**
@@ -1041,8 +1036,7 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
ctcmpc_dumpit((char *)&ch->ccw[3],
sizeof(struct ccw1) * 3);
- rc = ccw_device_start(ch->cdev, &ch->ccw[3],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[3], 0, 0xff, 0);
if (event == CTC_EVENT_TIMER)
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),
saveflags);
@@ -1361,8 +1355,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
ch->prof.send_stamp = jiffies;
if (do_debug_ccw)
ctcmpc_dumpit((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
ch->prof.doios_multi++;
if (rc != 0) {
priv->stats.tx_dropped += i;
@@ -1462,8 +1455,7 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
if (dolock)
spin_lock_irqsave(
get_ccwdev_lock(ch->cdev), saveflags);
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
if (dolock) /* see remark about conditional locking */
spin_unlock_irqrestore(
get_ccwdev_lock(ch->cdev), saveflags);
@@ -1569,8 +1561,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
if (event == CTC_EVENT_START)
/* see remark about conditional locking */
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
- rc = ccw_device_start(ch->cdev, &ch->ccw[0],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[0], 0, 0xff, 0);
if (event == CTC_EVENT_START)
spin_unlock_irqrestore(
get_ccwdev_lock(ch->cdev), saveflags);
@@ -1825,8 +1816,7 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
spin_lock_irqsave(get_ccwdev_lock(wch->cdev), saveflags);
wch->prof.send_stamp = jiffies;
- rc = ccw_device_start(wch->cdev, &wch->ccw[3],
- (unsigned long) wch, 0xff, 0);
+ rc = ccw_device_start(wch->cdev, &wch->ccw[3], 0, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(wch->cdev), saveflags);
if ((grp->sweep_req_pend_num == 0) &&
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index f63c5c871d3d..2117870ed855 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -569,8 +569,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
ch->prof.send_stamp = jiffies;
- rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (ccw_idx == 3)
ch->prof.doios_single++;
@@ -833,8 +832,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
ch->prof.send_stamp = jiffies;
- rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx], 0, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (ccw_idx == 3)
ch->prof.doios_single++;
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 1534420a0243..ab316baa8284 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -1523,8 +1523,7 @@ void mpc_action_send_discontact(unsigned long thischan)
unsigned long saveflags = 0;
spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
- rc = ccw_device_start(ch->cdev, &ch->ccw[15],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[15], 0, 0xff, 0);
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
if (rc != 0) {
@@ -1797,8 +1796,7 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
}
fsm_addtimer(&ch->timer, 5000 , CTC_EVENT_TIMER, ch);
- rc = ccw_device_start(ch->cdev, &ch->ccw[8],
- (unsigned long)ch, 0xff, 0);
+ rc = ccw_device_start(ch->cdev, &ch->ccw[8], 0, 0xff, 0);
if (gotlock) /* see remark above about conditional locking */
spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 9/9] s390/lcs: don't use intparm for channel IO
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
lcs passes an intparm when calling ccw_device_*(), even though lcs_irq()
later makes no use of this.
To reduce the confusion, consistently pass 0 as intparm instead.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Sebastian Ott <sebott@linux.ibm.com>
---
drivers/s390/net/lcs.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 2d9fe7e4ee40..8f08b0a2917c 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -504,7 +504,7 @@ lcs_clear_channel(struct lcs_channel *channel)
LCS_DBF_TEXT(4,trace,"clearch");
LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
- rc = ccw_device_clear(channel->ccwdev, (addr_t) channel);
+ rc = ccw_device_clear(channel->ccwdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) {
LCS_DBF_TEXT_(4, trace, "ecsc%s",
@@ -532,7 +532,7 @@ lcs_stop_channel(struct lcs_channel *channel)
LCS_DBF_TEXT_(4, trace, "%s", dev_name(&channel->ccwdev->dev));
channel->state = LCS_CH_STATE_INIT;
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
- rc = ccw_device_halt(channel->ccwdev, (addr_t) channel);
+ rc = ccw_device_halt(channel->ccwdev, 0);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
if (rc) {
LCS_DBF_TEXT_(4, trace, "ehsc%s",
@@ -1427,7 +1427,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
channel->state = LCS_CH_STATE_SUSPENDED;
if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) {
if (irb->scsw.cmd.cc != 0) {
- ccw_device_halt(channel->ccwdev, (addr_t) channel);
+ ccw_device_halt(channel->ccwdev, 0);
return;
}
/* The channel has been stopped by halt_IO. */
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 7/9] s390/qeth: streamline control code for promisc mode
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
We have logic to determine the desired promisc mode in _each_ code path.
Change things around so that there is a clean split between
(a) high-level code that selects the new mode, and (b) implementations
of the various mechanisms to program this mode.
This also keeps qeth_promisc_to_bridge() from polluting the debug logs
on each RX modeset.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
---
drivers/s390/net/qeth_core.h | 4 ++--
drivers/s390/net/qeth_core_main.c | 15 +++----------
drivers/s390/net/qeth_l2_main.c | 36 +++++++++++++++----------------
drivers/s390/net/qeth_l3_main.c | 24 ++++++---------------
4 files changed, 30 insertions(+), 49 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index f07bb7130280..72755a025b4d 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -653,6 +653,7 @@ struct qeth_card_info {
__u16 func_level;
char mcl_level[QETH_MCL_LENGTH + 1];
u8 open_when_online:1;
+ u8 promisc_mode:1;
u8 use_v1_blkt:1;
u8 is_vm_nic:1;
int mac_bits;
@@ -662,7 +663,6 @@ struct qeth_card_info {
int unique_id;
bool layer_enforced;
struct qeth_card_blkt blkt;
- enum qeth_ipa_promisc_modes promisc_mode;
__u32 diagass_support;
__u32 hwtrap;
};
@@ -1004,7 +1004,7 @@ void qeth_clear_ipacmd_list(struct qeth_card *);
int qeth_qdio_clear_card(struct qeth_card *, int);
void qeth_clear_working_pool_list(struct qeth_card *);
void qeth_drain_output_queues(struct qeth_card *card);
-void qeth_setadp_promisc_mode(struct qeth_card *);
+void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable);
int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 95996ce99145..44fbaa4f7264 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4015,23 +4015,14 @@ static int qeth_setadp_promisc_mode_cb(struct qeth_card *card,
return (cmd->hdr.return_code) ? -EIO : 0;
}
-void qeth_setadp_promisc_mode(struct qeth_card *card)
+void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable)
{
- enum qeth_ipa_promisc_modes mode;
- struct net_device *dev = card->dev;
+ enum qeth_ipa_promisc_modes mode = enable ? SET_PROMISC_MODE_ON :
+ SET_PROMISC_MODE_OFF;
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
QETH_CARD_TEXT(card, 4, "setprom");
-
- if (((dev->flags & IFF_PROMISC) &&
- (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
- (!(dev->flags & IFF_PROMISC) &&
- (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
- return;
- mode = SET_PROMISC_MODE_OFF;
- if (dev->flags & IFF_PROMISC)
- mode = SET_PROMISC_MODE_ON;
QETH_CARD_TEXT_(card, 4, "mode:%x", mode);
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 1f534f489a79..662bd51f922f 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -439,23 +439,14 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
return 0;
}
-static void qeth_promisc_to_bridge(struct qeth_card *card)
+static void qeth_l2_promisc_to_bridge(struct qeth_card *card, bool enable)
{
- struct net_device *dev = card->dev;
- enum qeth_ipa_promisc_modes promisc_mode;
int role;
int rc;
QETH_CARD_TEXT(card, 3, "pmisc2br");
- if (!card->options.sbp.reflect_promisc)
- return;
- promisc_mode = (dev->flags & IFF_PROMISC) ? SET_PROMISC_MODE_ON
- : SET_PROMISC_MODE_OFF;
- if (promisc_mode == card->info.promisc_mode)
- return;
-
- if (promisc_mode == SET_PROMISC_MODE_ON) {
+ if (enable) {
if (card->options.sbp.reflect_promisc_primary)
role = QETH_SBP_ROLE_PRIMARY;
else
@@ -464,14 +455,26 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)
role = QETH_SBP_ROLE_NONE;
rc = qeth_bridgeport_setrole(card, role);
- QETH_CARD_TEXT_(card, 2, "bpm%c%04x",
- (promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc);
+ QETH_CARD_TEXT_(card, 2, "bpm%c%04x", enable ? '+' : '-', rc);
if (!rc) {
card->options.sbp.role = role;
- card->info.promisc_mode = promisc_mode;
+ card->info.promisc_mode = enable;
}
+}
+
+static void qeth_l2_set_promisc_mode(struct qeth_card *card)
+{
+ bool enable = card->dev->flags & IFF_PROMISC;
+
+ if (card->info.promisc_mode == enable)
+ return;
+ if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
+ qeth_setadp_promisc_mode(card, enable);
+ else if (card->options.sbp.reflect_promisc)
+ qeth_l2_promisc_to_bridge(card, enable);
}
+
/* New MAC address is added to the hash table and marked to be written on card
* only if there is not in the hash table storage already
*
@@ -539,10 +542,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work)
}
}
- if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
- qeth_setadp_promisc_mode(card);
- else
- qeth_promisc_to_bridge(card);
+ qeth_l2_set_promisc_mode(card);
}
static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 2dd99f103671..54799fe6a700 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1435,27 +1435,19 @@ static void qeth_l3_stop_card(struct qeth_card *card)
flush_workqueue(card->event_wq);
}
-/*
- * test for and Switch promiscuous mode (on or off)
- * either for guestlan or HiperSocket Sniffer
- */
-static void
-qeth_l3_handle_promisc_mode(struct qeth_card *card)
+static void qeth_l3_set_promisc_mode(struct qeth_card *card)
{
- struct net_device *dev = card->dev;
+ bool enable = card->dev->flags & IFF_PROMISC;
- if (((dev->flags & IFF_PROMISC) &&
- (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
- (!(dev->flags & IFF_PROMISC) &&
- (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
+ if (card->info.promisc_mode == enable)
return;
if (IS_VM_NIC(card)) { /* Guestlan trace */
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
- qeth_setadp_promisc_mode(card);
+ qeth_setadp_promisc_mode(card, enable);
} else if (card->options.sniffer && /* HiperSockets trace */
qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
- if (dev->flags & IFF_PROMISC) {
+ if (enable) {
QETH_CARD_TEXT(card, 3, "+promisc");
qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
} else {
@@ -1502,11 +1494,9 @@ static void qeth_l3_rx_mode_work(struct work_struct *work)
addr->disp_flag = QETH_DISP_ADDR_DELETE;
}
}
-
- if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
- return;
}
- qeth_l3_handle_promisc_mode(card);
+
+ qeth_l3_set_promisc_mode(card);
}
static int qeth_l3_arp_makerc(u16 rc)
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 5/9] s390/qeth: merge qeth_reply struct into qeth_cmd_buffer
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
Except for card->read_cmd, every cmd we issue now passes through
qeth_send_control_data() and allocates a qeth_reply struct. The way we
use this struct requires additional refcounting, and pointer tracking.
Clean up things by moving most of qeth_reply's content into the main
cmd struct. This keeps things in one place, saves us the additional
refcounting and simplifies the overall code flow.
A nice little benefit is that we can now match incoming replies against
the pending requests themselves, without caching the requests' seqnos.
The qeth_reply struct stays around for a little bit longer in a shrunk
form, to avoid touching every single callback.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core.h | 26 +++---
drivers/s390/net/qeth_core_main.c | 126 +++++++++++-------------------
drivers/s390/net/qeth_core_mpc.h | 1 -
drivers/s390/net/qeth_l2_main.c | 2 +-
4 files changed, 58 insertions(+), 97 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index f6e58a51c366..f07bb7130280 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -572,16 +572,26 @@ struct qeth_channel {
atomic_t irq_pending;
};
+struct qeth_reply {
+ int (*callback)(struct qeth_card *card, struct qeth_reply *reply,
+ unsigned long data);
+ void *param;
+};
+
struct qeth_cmd_buffer {
+ struct list_head list;
+ struct completion done;
+ spinlock_t lock;
unsigned int length;
refcount_t ref_count;
struct qeth_channel *channel;
- struct qeth_reply *reply;
+ struct qeth_reply reply;
long timeout;
unsigned char *data;
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
unsigned int data_length);
+ int rc;
};
static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
@@ -627,18 +637,6 @@ struct qeth_seqno {
__u16 ipa;
};
-struct qeth_reply {
- struct list_head list;
- struct completion received;
- spinlock_t lock;
- int (*callback)(struct qeth_card *, struct qeth_reply *,
- unsigned long);
- u32 seqno;
- int rc;
- void *param;
- refcount_t refcnt;
-};
-
struct qeth_card_blkt {
int time_total;
int inter_packet;
@@ -994,6 +992,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card,
enum qeth_diags_cmds sub_cmd,
unsigned int data_length);
+void qeth_notify_cmd(struct qeth_cmd_buffer *iob, int reason);
void qeth_put_cmd(struct qeth_cmd_buffer *iob);
struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
@@ -1008,7 +1007,6 @@ void qeth_drain_output_queues(struct qeth_card *card);
void qeth_setadp_promisc_mode(struct qeth_card *);
int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *);
-void qeth_notify_reply(struct qeth_reply *reply, int reason);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
u16 cmd_length);
int qeth_query_switch_attributes(struct qeth_card *card,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3fc14f222dc3..95996ce99145 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -537,50 +537,28 @@ static int qeth_issue_next_read(struct qeth_card *card)
return ret;
}
-static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
-{
- struct qeth_reply *reply;
-
- reply = kzalloc(sizeof(*reply), GFP_KERNEL);
- if (reply) {
- refcount_set(&reply->refcnt, 1);
- init_completion(&reply->received);
- spin_lock_init(&reply->lock);
- }
- return reply;
-}
-
-static void qeth_get_reply(struct qeth_reply *reply)
-{
- refcount_inc(&reply->refcnt);
-}
-
-static void qeth_put_reply(struct qeth_reply *reply)
-{
- if (refcount_dec_and_test(&reply->refcnt))
- kfree(reply);
-}
-
-static void qeth_enqueue_reply(struct qeth_card *card, struct qeth_reply *reply)
+static void qeth_enqueue_cmd(struct qeth_card *card,
+ struct qeth_cmd_buffer *iob)
{
spin_lock_irq(&card->lock);
- list_add_tail(&reply->list, &card->cmd_waiter_list);
+ list_add_tail(&iob->list, &card->cmd_waiter_list);
spin_unlock_irq(&card->lock);
}
-static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply)
+static void qeth_dequeue_cmd(struct qeth_card *card,
+ struct qeth_cmd_buffer *iob)
{
spin_lock_irq(&card->lock);
- list_del(&reply->list);
+ list_del(&iob->list);
spin_unlock_irq(&card->lock);
}
-void qeth_notify_reply(struct qeth_reply *reply, int reason)
+void qeth_notify_cmd(struct qeth_cmd_buffer *iob, int reason)
{
- reply->rc = reason;
- complete(&reply->received);
+ iob->rc = reason;
+ complete(&iob->done);
}
-EXPORT_SYMBOL_GPL(qeth_notify_reply);
+EXPORT_SYMBOL_GPL(qeth_notify_cmd);
static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
struct qeth_card *card)
@@ -658,14 +636,14 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
void qeth_clear_ipacmd_list(struct qeth_card *card)
{
- struct qeth_reply *reply;
+ struct qeth_cmd_buffer *iob;
unsigned long flags;
QETH_CARD_TEXT(card, 4, "clipalst");
spin_lock_irqsave(&card->lock, flags);
- list_for_each_entry(reply, &card->cmd_waiter_list, list)
- qeth_notify_reply(reply, -EIO);
+ list_for_each_entry(iob, &card->cmd_waiter_list, list)
+ qeth_notify_cmd(iob, -EIO);
spin_unlock_irqrestore(&card->lock, flags);
}
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
@@ -694,8 +672,6 @@ static int qeth_check_idx_response(struct qeth_card *card,
void qeth_put_cmd(struct qeth_cmd_buffer *iob)
{
if (refcount_dec_and_test(&iob->ref_count)) {
- if (iob->reply)
- qeth_put_reply(iob->reply);
kfree(iob->data);
kfree(iob);
}
@@ -711,10 +687,7 @@ static void qeth_release_buffer_cb(struct qeth_card *card,
static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc)
{
- struct qeth_reply *reply = iob->reply;
-
- if (reply)
- qeth_notify_reply(reply, rc);
+ qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob);
}
@@ -738,6 +711,9 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
return NULL;
}
+ init_completion(&iob->done);
+ spin_lock_init(&iob->lock);
+ INIT_LIST_HEAD(&iob->list);
refcount_set(&iob->ref_count, 1);
iob->channel = channel;
iob->timeout = timeout;
@@ -750,9 +726,10 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob,
unsigned int data_length)
{
+ struct qeth_cmd_buffer *request = NULL;
struct qeth_ipa_cmd *cmd = NULL;
struct qeth_reply *reply = NULL;
- struct qeth_reply *r;
+ struct qeth_cmd_buffer *tmp;
unsigned long flags;
int rc = 0;
@@ -787,39 +764,39 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
/* match against pending cmd requests */
spin_lock_irqsave(&card->lock, flags);
- list_for_each_entry(r, &card->cmd_waiter_list, list) {
- if ((r->seqno == QETH_IDX_COMMAND_SEQNO) ||
- (cmd && (r->seqno == cmd->hdr.seqno))) {
- reply = r;
+ list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
+ if (!IS_IPA(tmp->data) ||
+ __ipa_cmd(tmp)->hdr.seqno == cmd->hdr.seqno) {
+ request = tmp;
/* take the object outside the lock */
- qeth_get_reply(reply);
+ qeth_get_cmd(request);
break;
}
}
spin_unlock_irqrestore(&card->lock, flags);
- if (!reply)
+ if (!request)
goto out;
+ reply = &request->reply;
if (!reply->callback) {
rc = 0;
goto no_callback;
}
- spin_lock_irqsave(&reply->lock, flags);
- if (reply->rc)
+ spin_lock_irqsave(&request->lock, flags);
+ if (request->rc)
/* Bail out when the requestor has already left: */
- rc = reply->rc;
+ rc = request->rc;
else
rc = reply->callback(card, reply, cmd ? (unsigned long)cmd :
(unsigned long)iob);
- spin_unlock_irqrestore(&reply->lock, flags);
+ spin_unlock_irqrestore(&request->lock, flags);
no_callback:
if (rc <= 0)
- qeth_notify_reply(reply, rc);
- qeth_put_reply(reply);
-
+ qeth_notify_cmd(request, rc);
+ qeth_put_cmd(request);
out:
memcpy(&card->seqno.pdu_hdr_ack,
QETH_PDU_HEADER_SEQ_NO(iob->data),
@@ -1658,7 +1635,6 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card,
memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
&card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
- iob->reply->seqno = QETH_IDX_COMMAND_SEQNO;
iob->callback = qeth_release_buffer_cb;
}
@@ -1709,29 +1685,19 @@ static int qeth_send_control_data(struct qeth_card *card,
void *reply_param)
{
struct qeth_channel *channel = iob->channel;
+ struct qeth_reply *reply = &iob->reply;
long timeout = iob->timeout;
int rc;
- struct qeth_reply *reply = NULL;
QETH_CARD_TEXT(card, 2, "sendctl");
- reply = qeth_alloc_reply(card);
- if (!reply) {
- qeth_put_cmd(iob);
- return -ENOMEM;
- }
reply->callback = reply_cb;
reply->param = reply_param;
- /* pairs with qeth_put_cmd(): */
- qeth_get_reply(reply);
- iob->reply = reply;
-
timeout = wait_event_interruptible_timeout(card->wait_q,
qeth_trylock_channel(channel),
timeout);
if (timeout <= 0) {
- qeth_put_reply(reply);
qeth_put_cmd(iob);
return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
}
@@ -1740,7 +1706,7 @@ static int qeth_send_control_data(struct qeth_card *card,
iob->finalize(card, iob);
QETH_DBF_HEX(CTRL, 2, iob->data, min(iob->length, QETH_DBF_CTRL_LEN));
- qeth_enqueue_reply(card, reply);
+ qeth_enqueue_cmd(card, iob);
/* This pairs with iob->callback, and keeps the iob alive after IO: */
qeth_get_cmd(iob);
@@ -1754,34 +1720,33 @@ static int qeth_send_control_data(struct qeth_card *card,
QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
CARD_DEVID(card), rc);
QETH_CARD_TEXT_(card, 2, " err%d", rc);
- qeth_dequeue_reply(card, reply);
+ qeth_dequeue_cmd(card, iob);
qeth_put_cmd(iob);
atomic_set(&channel->irq_pending, 0);
wake_up(&card->wait_q);
goto out;
}
- timeout = wait_for_completion_interruptible_timeout(&reply->received,
+ timeout = wait_for_completion_interruptible_timeout(&iob->done,
timeout);
if (timeout <= 0)
rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
- qeth_dequeue_reply(card, reply);
+ qeth_dequeue_cmd(card, iob);
if (reply_cb) {
/* Wait until the callback for a late reply has completed: */
- spin_lock_irq(&reply->lock);
+ spin_lock_irq(&iob->lock);
if (rc)
/* Zap any callback that's still pending: */
- reply->rc = rc;
- spin_unlock_irq(&reply->lock);
+ iob->rc = rc;
+ spin_unlock_irq(&iob->lock);
}
if (!rc)
- rc = reply->rc;
+ rc = iob->rc;
out:
- qeth_put_reply(reply);
qeth_put_cmd(iob);
return rc;
}
@@ -1822,7 +1787,7 @@ static void qeth_read_conf_data_cb(struct qeth_card *card,
nd->nd3.model[2] <= 0xF4;
out:
- qeth_notify_reply(iob->reply, rc);
+ qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob);
}
@@ -1914,7 +1879,7 @@ static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);
out:
- qeth_notify_reply(iob->reply, rc);
+ qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob);
}
@@ -1942,7 +1907,7 @@ static void qeth_idx_activate_write_channel_cb(struct qeth_card *card,
}
out:
- qeth_notify_reply(iob->reply, rc);
+ qeth_notify_cmd(iob, rc);
qeth_put_cmd(iob);
}
@@ -2675,8 +2640,7 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card,
qeth_mpc_finalize_cmd(card, iob);
/* override with IPA-specific values: */
- __ipa_cmd(iob)->hdr.seqno = card->seqno.ipa;
- iob->reply->seqno = card->seqno.ipa++;
+ __ipa_cmd(iob)->hdr.seqno = card->seqno.ipa++;
}
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 75b5834ed28d..6420b58cf42b 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -27,7 +27,6 @@ extern unsigned char IPA_PDU_HEADER[];
#define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ)
-#define QETH_IDX_COMMAND_SEQNO 0xffff0000
#define QETH_CLEAR_CHANNEL_PARM -10
#define QETH_HALT_CHANNEL_PARM -11
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c524c8bff3c7..ad7ee3bfd63c 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1003,7 +1003,7 @@ static void qeth_osn_assist_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob,
unsigned int data_length)
{
- qeth_notify_reply(iob->reply, 0);
+ qeth_notify_cmd(iob, 0);
qeth_put_cmd(iob);
}
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 2/9] s390/qeth: propagate length of processed cmd IO data to callback
From: Julian Wiedmann @ 2019-08-20 14:46 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-s390, Heiko Carstens, Stefan Raspl, Ursula Braun,
Julian Wiedmann
In-Reply-To: <20190820144643.64041-1-jwi@linux.ibm.com>
When an cmd IO completes in qeth_irq(), calculate how much data was
processed by the device and pass this value to the cmd's callback.
This allows cmds that retrieve data from the device to check whether
sufficient data was received, so we do that in qeth_read_conf_data_cb().
Suggested-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
---
drivers/s390/net/qeth_core.h | 3 ++-
drivers/s390/net/qeth_core_main.c | 40 ++++++++++++++++++++++++-------
drivers/s390/net/qeth_l2_main.c | 3 ++-
3 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 47e01cdd1775..4e21aa8edb13 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -580,7 +580,8 @@ struct qeth_cmd_buffer {
long timeout;
unsigned char *data;
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
- void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
+ void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ unsigned int data_length);
};
static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 50f2773a1f8c..f7a8b8301eb4 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -63,7 +63,8 @@ static struct device *qeth_core_root_dev;
static struct lock_class_key qdio_out_skb_queue_key;
static void qeth_issue_next_read_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob);
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length);
static void qeth_free_buffer_pool(struct qeth_card *);
static int qeth_qdio_establish(struct qeth_card *);
static void qeth_free_qdio_queues(struct qeth_card *card);
@@ -702,7 +703,8 @@ void qeth_put_cmd(struct qeth_cmd_buffer *iob)
EXPORT_SYMBOL_GPL(qeth_put_cmd);
static void qeth_release_buffer_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
qeth_put_cmd(iob);
}
@@ -745,7 +747,8 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
EXPORT_SYMBOL_GPL(qeth_alloc_cmd);
static void qeth_issue_next_read_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
struct qeth_ipa_cmd *cmd = NULL;
struct qeth_reply *reply = NULL;
@@ -1072,8 +1075,16 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
}
}
- if (iob && iob->callback)
- iob->callback(card, iob);
+ if (iob) {
+ /* sanity check: */
+ if (irb->scsw.cmd.count > iob->length) {
+ qeth_cancel_cmd(iob, -EIO);
+ goto out;
+ }
+ if (iob->callback)
+ iob->callback(card, iob,
+ iob->length - irb->scsw.cmd.count);
+ }
out:
wake_up(&card->wait_q);
@@ -1782,12 +1793,20 @@ struct qeth_node_desc {
};
static void qeth_read_conf_data_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
struct qeth_node_desc *nd = (struct qeth_node_desc *) iob->data;
+ int rc = 0;
u8 *tag;
QETH_CARD_TEXT(card, 2, "cfgunit");
+
+ if (data_length < sizeof(*nd)) {
+ rc = -EINVAL;
+ goto out;
+ }
+
card->info.is_vm_nic = nd->nd1.plant[0] == _ascebc['V'] &&
nd->nd1.plant[1] == _ascebc['M'];
tag = (u8 *)&nd->nd1.tag;
@@ -1802,7 +1821,8 @@ static void qeth_read_conf_data_cb(struct qeth_card *card,
nd->nd3.model[2] >= 0xF1 &&
nd->nd3.model[2] <= 0xF4;
- qeth_notify_reply(iob->reply, 0);
+out:
+ qeth_notify_reply(iob->reply, rc);
qeth_put_cmd(iob);
}
@@ -1865,7 +1885,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card,
}
static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
struct qeth_channel *channel = iob->channel;
u16 peer_level;
@@ -1898,7 +1919,8 @@ static void qeth_idx_activate_read_channel_cb(struct qeth_card *card,
}
static void qeth_idx_activate_write_channel_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
struct qeth_channel *channel = iob->channel;
u16 peer_level;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index cbead3d1b2fd..c524c8bff3c7 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1000,7 +1000,8 @@ struct qeth_discipline qeth_l2_discipline = {
EXPORT_SYMBOL_GPL(qeth_l2_discipline);
static void qeth_osn_assist_cb(struct qeth_card *card,
- struct qeth_cmd_buffer *iob)
+ struct qeth_cmd_buffer *iob,
+ unsigned int data_length)
{
qeth_notify_reply(iob->reply, 0);
qeth_put_cmd(iob);
--
2.17.1
^ permalink raw reply related
* [PATCH 2/6] dt-bindings: net: sun8i-a83t-emac: Add phy-io-supply property
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
Some PHYs require separate power supply for I/O pins in some modes
of operation. Add phy-io-supply property, to allow enabling this
power supply.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
index 304f244e9ab5..782e202aa124 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
@@ -47,6 +47,10 @@ properties:
description:
PHY regulator
+ phy-io-supply:
+ description:
+ PHY I/O pins regulator
+
required:
- compatible
- reg
--
2.22.1
^ permalink raw reply related
* [PATCH 6/6] arm64: dts: allwinner: orange-pi-3: Enable ethernet
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
Orange Pi 3 has two regulators that power the Realtek RTL8211E
PHY. According to the datasheet, both regulators need to be enabled
at the same time, or that "phy-io" should be enabled slightly earlier
than "phy" regulator.
RTL8211E/RTL8211EG datasheet says:
Note 4: 2.5V (or 1.8/1.5V) RGMII power should be risen simultaneously
or slightly earlier than 3.3V power. Rising 2.5V (or 1.8/1.5V) power
later than 3.3V power may lead to errors.
The driver ensures the regulator enable ordering. The timing is set
in DT via startup-delay-us.
We also need to wait at least 30ms after power-up/reset, before
accessing the PHY registers.
All values of RX/TX delay were tested exhaustively and a middle one
of the range of working values was chosen.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../dts/allwinner/sun50i-h6-orangepi-3.dts | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
index eda9d5f640b9..18349e60b8c6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
@@ -15,6 +15,7 @@
aliases {
serial0 = &uart0;
+ ethernet0 = &emac;
};
chosen {
@@ -56,6 +57,15 @@
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
+
+ reg_gmac_2v5: gmac-2v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "gmac-2v5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ enable-active-high;
+ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+ };
};
&cpu0 {
@@ -74,6 +84,35 @@
status = "okay";
};
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_rgmii_pins>;
+ phy-mode = "rgmii";
+ phy-handle = <&ext_rgmii_phy>;
+ /*
+ * The board uses 2.5V RGMII signalling. Power sequence to enable
+ * the phy is to enable GMAC-2V5 and GMAC-3V (aldo2) power rails
+ * at the same time and to wait 100ms. The driver enables phy-io
+ * first. Delay is achieved with enable-ramp-delay on reg_aldo2.
+ */
+ phy-supply = <®_aldo2>;
+ phy-io-supply = <®_gmac_2v5>;
+ allwinner,rx-delay-ps = <1500>;
+ allwinner,tx-delay-ps = <700>;
+ status = "okay";
+};
+
+&mdio {
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+
+ reset-gpios = <&pio 3 14 GPIO_ACTIVE_LOW>; /* PD14 */
+ reset-assert-us = <15000>;
+ reset-deassert-us = <40000>;
+ };
+};
+
&hdmi {
status = "okay";
};
@@ -136,6 +175,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc33-audio-tv-ephy-mac";
+ regulator-enable-ramp-delay = <100000>;
};
/* ALDO3 is shorted to CLDO1 */
--
2.22.1
^ permalink raw reply related
* [PATCH 5/6] net: stmmac: sun8i: Add support for enabling a regulator for PHY I/O pins
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
Orange Pi 3 has two regulators that power the Realtek RTL8211E. According
to the phy datasheet, both regulators need to be enabled at the same time.
Add support for the second optional regulator, "phy-io", to the glue
driver.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 31 ++++++++++++++++---
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index e7df30d3cab1..e96337b7cd12 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -61,6 +61,8 @@ struct emac_variant {
* @ephy_clk: reference to the optional EPHY clock for
* the internal PHY
* @regulator_phy: reference to the optional regulator
+ * @regulator_phy_io: reference to the optional regulator for
+ * PHY I/O pins
* @rst_ephy: reference to the optional EPHY reset for
* the internal PHY
* @variant: reference to the current board variant
@@ -72,6 +74,7 @@ struct sunxi_priv_data {
struct clk *tx_clk;
struct clk *ephy_clk;
struct regulator *regulator_phy;
+ struct regulator *regulator_phy_io;
struct reset_control *rst_ephy;
const struct emac_variant *variant;
struct regmap_field *regmap_field;
@@ -530,21 +533,30 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
struct sunxi_priv_data *gmac = priv;
int ret;
+ ret = regulator_enable(gmac->regulator_phy_io);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to enable PHY I/O regulator\n");
+ return ret;
+ }
+
ret = regulator_enable(gmac->regulator_phy);
if (ret) {
dev_err(&pdev->dev, "Fail to enable PHY regulator\n");
- return ret;
+ goto err_disable_regulator_phy_io;
}
ret = clk_prepare_enable(gmac->tx_clk);
if (ret) {
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
dev_err(&pdev->dev, "Could not enable AHB clock\n");
- return ret;
+ goto err_disable_regulator_phy;
}
return 0;
+err_disable_regulator_phy:
+ regulator_disable(gmac->regulator_phy);
+err_disable_regulator_phy_io:
+ regulator_disable(gmac->regulator_phy_io);
+ return ret;
}
static void sun8i_dwmac_core_init(struct mac_device_info *hw,
@@ -993,6 +1005,7 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
clk_disable_unprepare(gmac->tx_clk);
regulator_disable(gmac->regulator_phy);
+ regulator_disable(gmac->regulator_phy_io);
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1136,6 +1149,16 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
return ret;
}
+ /* Optional regulator for PHY I/O pins */
+ gmac->regulator_phy_io = devm_regulator_get(dev, "phy-io");
+ if (IS_ERR(gmac->regulator_phy_io)) {
+ ret = PTR_ERR(gmac->regulator_phy_io);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get PHY I/O regulator (%d)\n",
+ ret);
+ return ret;
+ }
+
/* The "GMAC clock control" register might be located in the
* CCU address range (on the R40), or the system control address
* range (on most other sun8i and later SoCs).
--
2.22.1
^ permalink raw reply related
* [PATCH 4/6] net: stmmac: sun8i: Rename PHY regulator variable to regulator_phy
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
We'll be adding further optional regulators, and this makes it clearer
what the regulator is for.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 32 ++++++++++---------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 3e951a11aec3..e7df30d3cab1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -57,19 +57,21 @@ struct emac_variant {
};
/* struct sunxi_priv_data - hold all sunxi private data
- * @tx_clk: reference to MAC TX clock
- * @ephy_clk: reference to the optional EPHY clock for the internal PHY
- * @regulator: reference to the optional regulator
- * @rst_ephy: reference to the optional EPHY reset for the internal PHY
- * @variant: reference to the current board variant
- * @regmap: regmap for using the syscon
- * @internal_phy_powered: Does the internal PHY is enabled
- * @mux_handle: Internal pointer used by mdio-mux lib
+ * @tx_clk: reference to MAC TX clock
+ * @ephy_clk: reference to the optional EPHY clock for
+ * the internal PHY
+ * @regulator_phy: reference to the optional regulator
+ * @rst_ephy: reference to the optional EPHY reset for
+ * the internal PHY
+ * @variant: reference to the current board variant
+ * @regmap: regmap for using the syscon
+ * @internal_phy_powered: Does the internal PHY is enabled
+ * @mux_handle: Internal pointer used by mdio-mux lib
*/
struct sunxi_priv_data {
struct clk *tx_clk;
struct clk *ephy_clk;
- struct regulator *regulator;
+ struct regulator *regulator_phy;
struct reset_control *rst_ephy;
const struct emac_variant *variant;
struct regmap_field *regmap_field;
@@ -528,9 +530,9 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
struct sunxi_priv_data *gmac = priv;
int ret;
- ret = regulator_enable(gmac->regulator);
+ ret = regulator_enable(gmac->regulator_phy);
if (ret) {
- dev_err(&pdev->dev, "Fail to enable regulator\n");
+ dev_err(&pdev->dev, "Fail to enable PHY regulator\n");
return ret;
}
@@ -990,7 +992,7 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
clk_disable_unprepare(gmac->tx_clk);
- regulator_disable(gmac->regulator);
+ regulator_disable(gmac->regulator_phy);
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1126,9 +1128,9 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
}
/* Optional regulator for PHY */
- gmac->regulator = devm_regulator_get(dev, "phy");
- if (IS_ERR(gmac->regulator)) {
- ret = PTR_ERR(gmac->regulator);
+ gmac->regulator_phy = devm_regulator_get(dev, "phy");
+ if (IS_ERR(gmac->regulator_phy)) {
+ ret = PTR_ERR(gmac->regulator_phy);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get PHY regulator (%d)\n", ret);
return ret;
--
2.22.1
^ permalink raw reply related
* [PATCH 3/6] net: stmmac: sun8i: Use devm_regulator_get for PHY regulator
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
Use devm_regulator_get instead of devm_regulator_get_optional and rely
on dummy supply. This avoids NULL checks before regulator_enable/disable
calls.
This path also improves error reporting, because we now report both
use of dummy supply and error during registration with more detail,
instead of generic info level message "No regulator found" that
was reported previously on errors and lack of regulator property in DT.
Finally, we'll be adding further optional regulators, and the overall
code will be simpler.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 23 ++++++++-----------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 4083019c547a..3e951a11aec3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -528,12 +528,10 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
struct sunxi_priv_data *gmac = priv;
int ret;
- if (gmac->regulator) {
- ret = regulator_enable(gmac->regulator);
- if (ret) {
- dev_err(&pdev->dev, "Fail to enable regulator\n");
- return ret;
- }
+ ret = regulator_enable(gmac->regulator);
+ if (ret) {
+ dev_err(&pdev->dev, "Fail to enable regulator\n");
+ return ret;
}
ret = clk_prepare_enable(gmac->tx_clk);
@@ -992,8 +990,7 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
clk_disable_unprepare(gmac->tx_clk);
- if (gmac->regulator)
- regulator_disable(gmac->regulator);
+ regulator_disable(gmac->regulator);
}
static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
@@ -1129,12 +1126,12 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
}
/* Optional regulator for PHY */
- gmac->regulator = devm_regulator_get_optional(dev, "phy");
+ gmac->regulator = devm_regulator_get(dev, "phy");
if (IS_ERR(gmac->regulator)) {
- if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- dev_info(dev, "No regulator found\n");
- gmac->regulator = NULL;
+ ret = PTR_ERR(gmac->regulator);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get PHY regulator (%d)\n", ret);
+ return ret;
}
/* The "GMAC clock control" register might be located in the
--
2.22.1
^ permalink raw reply related
* [PATCH 0/6] Add ethernet support for Orange Pi 3
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
From: Ondrej Jirman <megous@megous.com>
This series implements ethernet support for Xunlong Orange Pi 3 board, by:
- making small cleanups of existing dwmac-sun8i code
- adding DT bindings docummentation
- adding support for phy-io-supply to dwmac-sun8i code
- adding DT configuration for Orange Pi 3 board
For some people, ethernet doesn't work after reboot because u-boot doesn't
support AXP805 PMIC, and will not turn off the etherent PHY regulators.
So the regulator controlled by gpio will be shut down, but the other one
controlled by the AXP PMIC will not.
This is a problem only when running with a builtin driver. This needs
to be fixed in u-boot and should not prevent these patches from being
merged.
This evolved out of the Orange Pi 3 patches series, as I didn't want
to stretch that out any longer.
Please take a look.
thank you and regards,
Ondrej Jirman
Ondrej Jirman (6):
dt-bindings: net: sun8i-a83t-emac: Add phy-supply property
dt-bindings: net: sun8i-a83t-emac: Add phy-io-supply property
net: stmmac: sun8i: Use devm_regulator_get for PHY regulator
net: stmmac: sun8i: Rename PHY regulator variable to regulator_phy
net: stmmac: sun8i: Add support for enabling a regulator for PHY I/O
pins
arm64: dts: allwinner: orange-pi-3: Enable ethernet
.../net/allwinner,sun8i-a83t-emac.yaml | 8 ++
.../dts/allwinner/sun50i-h6-orangepi-3.dts | 40 ++++++++++
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 74 ++++++++++++-------
3 files changed, 96 insertions(+), 26 deletions(-)
--
2.22.1
^ permalink raw reply
* [PATCH 1/6] dt-bindings: net: sun8i-a83t-emac: Add phy-supply property
From: megous @ 2019-08-20 14:53 UTC (permalink / raw)
To: David S. Miller, Rob Herring, Mark Rutland, Maxime Ripard,
Chen-Yu Tsai, Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu,
Maxime Coquelin
Cc: Ondrej Jirman, netdev, devicetree, linux-arm-kernel, linux-kernel,
linux-stm32
In-Reply-To: <20190820145343.29108-1-megous@megous.com>
From: Ondrej Jirman <megous@megous.com>
This is already supported by the driver, but is missing from the
bindings.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
.../devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
index 3fb0714e761e..304f244e9ab5 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml
@@ -43,6 +43,10 @@ properties:
Phandle to the device containing the EMAC or GMAC clock
register
+ phy-supply:
+ description:
+ PHY regulator
+
required:
- compatible
- reg
--
2.22.1
^ permalink raw reply related
* Re: [PATCH -next] bpf: Use PTR_ERR_OR_ZERO in xsk_map_inc()
From: Daniel Borkmann @ 2019-08-20 15:09 UTC (permalink / raw)
To: YueHaibing, bjorn.topel, magnus.karlsson, jonathan.lemon, ast,
kafai, songliubraving, yhs, john.fastabend
Cc: netdev, bpf, kernel-janitors
In-Reply-To: <20190820013652.147041-1-yuehaibing@huawei.com>
On 8/20/19 3:36 AM, YueHaibing wrote:
> Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH bpf-next v2] bpf: add BTF ids in procfs for file descriptors to BTF objects
From: Daniel Borkmann @ 2019-08-20 15:10 UTC (permalink / raw)
To: Quentin Monnet, Alexei Starovoitov; +Cc: bpf, netdev, oss-drivers
In-Reply-To: <20190820135346.7593-1-quentin.monnet@netronome.com>
On 8/20/19 3:53 PM, Quentin Monnet wrote:
> Implement the show_fdinfo hook for BTF FDs file operations, and make it
> print the id of the BTF object. This allows for a quick retrieval of the
> BTF id from its FD; or it can help understanding what type of object
> (BTF) the file descriptor points to.
>
> v2:
> - Do not expose data_size, only btf_id, in FD info.
>
> Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH bpf-next V9 1/3] bpf: new helper to obtain namespace data from current task
From: Carlos Antonio Neira Bustos @ 2019-08-20 15:10 UTC (permalink / raw)
To: Yonghong Song
Cc: netdev@vger.kernel.org, ebiederm@xmission.com, brouer@redhat.com,
bpf@vger.kernel.org
In-Reply-To: <445a4535-b8cc-b6bc-717b-a5736030533a@fb.com>
Hi Yonghong,
Thanks for taking the time to review this.
> > + *
> > + * **-EINVAL** if *size_of_pidns* is not valid or unable to get ns, pid
> > + * or tgid of the current task.
> > + *
> > + * **-ECHILD** if /proc/self/ns/pid does not exists.
> > + *
> > + * **-ENOTDIR** if /proc/self/ns does not exists.
>
> Let us remove ECHILD and ENOTDIR and replace it with ENOENT as I
> described below.
>
> Please *do verify* what happens when namespaces or pid_ns are not
> configured.
>
I have tested kernel configurations without namespace support and with
namespace support but without pid namespaces, the helper returns -EINVAL
on both cases, now it should return -ENOENT.
> > +struct bpf_pidns_info {
> > + __u32 dev;
>
> Please add a comment for dev for how device major and minor number are
> derived. User space gets device major and minor number, they need to
> compare to the corresponding major/minor numbers returned by this helper.
>
> > + __u32 nsid;
> > + __u32 tgid;
> > + __u32 pid;
> > +};
>
What do you think of this comment ?
struct bpf_pidns_info {
__u32 dev; /* major/minor numbers from /proc/self/ns/pid.
* User space gets device major and minor numbers from
* the same device that need to be compared against the
* major/minor numbers returned by this helper.
*/
__u32 nsid;
__u32 tgid;
__u32 pid;
};
>
> Please put an empty line. As a general rule for readability,
> put an empty line if control flow is interrupted, e.g., by
> "return", "break" or "continue". At least this is what
> I saw most in bpf mailing list.
>
I'll fix it in version 10.
> > + len = strlen(pidns_path) + 1;
> > + memcpy((char *)tmp->name, pidns_path, len);
> > + tmp->uptr = NULL;
> > + tmp->aname = NULL;
> > + tmp->refcnt = 1;
> > + ret = filename_lookup(AT_FDCWD, tmp, 0, &kp, NULL);
> Adding below to free kmem cache memory
> kmem_cache_free(names_cachep, fname);
>
I think we don't need to call kmem_cache_free as filename_lookup
calls putname that calls kmem_cache_free.
Thanks a lot for your help.
Bests
> In the above, we checked task_active_pid_ns().
> If not returning NULL, we have a valid pid ns. So the above
> filename_lookup should not go wrong. We can still keep
> the error checking though.
>
> > + if (ret) {
> > + memset((void *)pidns_info, 0, (size_t) size);
> > + return ret;
>
>
I think we could get rid of this.
On Tue, Aug 13, 2019 at 10:35:42PM +0000, Yonghong Song wrote:
>
>
> On 8/13/19 11:47 AM, Carlos Neira wrote:
> > From: Carlos <cneirabustos@gmail.com>
> >
> > New bpf helper bpf_get_current_pidns_info.
> > This helper obtains the active namespace from current and returns
> > pid, tgid, device and namespace id as seen from that namespace,
> > allowing to instrument a process inside a container.
> >
> > Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
> > ---
> > fs/internal.h | 2 --
> > fs/namei.c | 1 -
> > include/linux/bpf.h | 1 +
> > include/linux/namei.h | 4 +++
> > include/uapi/linux/bpf.h | 31 ++++++++++++++++++++++-
> > kernel/bpf/core.c | 1 +
> > kernel/bpf/helpers.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
> > kernel/trace/bpf_trace.c | 2 ++
> > 8 files changed, 102 insertions(+), 4 deletions(-)
>
> I prefer to break this into two patches to reduce
> the potential merging conflicts:
> patch 1: fs/internal.h, fs/namei.c, include/linux/namei.h
> patch 2: rest of changes
> patch 1 is simply a preparing patches to make filename_lookup
> available later.
>
> >
> > diff --git a/fs/internal.h b/fs/internal.h
> > index 315fcd8d237c..6647e15dd419 100644
> > --- a/fs/internal.h
> > +++ b/fs/internal.h
> > @@ -59,8 +59,6 @@ extern int finish_clean_context(struct fs_context *fc);
> > /*
> > * namei.c
> > */
> > -extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
> > - struct path *path, struct path *root);
> > extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *);
> > extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
> > const char *, unsigned int, struct path *);
> > diff --git a/fs/namei.c b/fs/namei.c
> > index 209c51a5226c..a89fc72a4a10 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -19,7 +19,6 @@
> > #include <linux/export.h>
> > #include <linux/kernel.h>
> > #include <linux/slab.h>
> > -#include <linux/fs.h>
> > #include <linux/namei.h>
> > #include <linux/pagemap.h>
> > #include <linux/fsnotify.h>
> > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > index f9a506147c8a..e4adf5e05afd 100644
> > --- a/include/linux/bpf.h
> > +++ b/include/linux/bpf.h
> > @@ -1050,6 +1050,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
> > extern const struct bpf_func_proto bpf_strtol_proto;
> > extern const struct bpf_func_proto bpf_strtoul_proto;
> > extern const struct bpf_func_proto bpf_tcp_sock_proto;
> > +extern const struct bpf_func_proto bpf_get_current_pidns_info_proto;
> >
> > /* Shared helpers among cBPF and eBPF. */
> > void bpf_user_rnd_init_once(void);
> > diff --git a/include/linux/namei.h b/include/linux/namei.h
> > index 9138b4471dbf..b45c8b6f7cb4 100644
> > --- a/include/linux/namei.h
> > +++ b/include/linux/namei.h
> > @@ -6,6 +6,7 @@
> > #include <linux/path.h>
> > #include <linux/fcntl.h>
> > #include <linux/errno.h>
> > +#include <linux/fs.h>
> >
> > enum { MAX_NESTED_LINKS = 8 };
> >
> > @@ -97,6 +98,9 @@ extern void unlock_rename(struct dentry *, struct dentry *);
> >
> > extern void nd_jump_link(struct path *path);
> >
> > +extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
> > + struct path *path, struct path *root);
> > +
> > static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
> > {
> > ((char *) name)[min(len, maxlen)] = '\0';
> > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> > index 4393bd4b2419..db241857ec15 100644
> > --- a/include/uapi/linux/bpf.h
> > +++ b/include/uapi/linux/bpf.h
> > @@ -2741,6 +2741,28 @@ union bpf_attr {
> > * **-EOPNOTSUPP** kernel configuration does not enable SYN cookies
> > *
> > * **-EPROTONOSUPPORT** IP packet version is not 4 or 6
> > + *
> > + * int bpf_get_current_pidns_info(struct bpf_pidns_info *pidns, u32 size_of_pidns)
>
> size_of_pidns => size.
>
> > + * Description
> > + * Copies into *pidns* pid, namespace id and tgid as seen by the
> Copies => Copy.
> Maybe something like below:
> Get tgid, pid and namespace id as seen by the current namespace, and
> device major/minor numbers from device /proc/self/ns/pid. Such
> information is stored in *pidns* of size *size*.
>
> > + * current namespace and also device from /proc/self/ns/pid.
> > + * *size_of_pidns* must be the size of *pidns*
> > + *
> > + * This helper is used when pid filtering is needed inside a
> > + * container as bpf_get_current_tgid() helper returns always the
>
> returns always => always returns.
>
> > + * pid id as seen by the root namespace.
> > + * Return
> > + * 0 on success
> > + *
> > + * **-EINVAL** if *size_of_pidns* is not valid or unable to get ns, pid
> > + * or tgid of the current task.
> > + *
> > + * **-ECHILD** if /proc/self/ns/pid does not exists.
> > + *
> > + * **-ENOTDIR** if /proc/self/ns does not exists.
>
> Let us remove ECHILD and ENOTDIR and replace it with ENOENT as I
> described below.
>
> Please *do verify* what happens when namespaces or pid_ns are not
> configured.
>
> > + *
> > + * **-ENOMEM** if allocation fails.
>
> helper internal allocation fails.
>
> > + *
> > */
> > #define __BPF_FUNC_MAPPER(FN) \
> > FN(unspec), \
> > @@ -2853,7 +2875,8 @@ union bpf_attr {
> > FN(sk_storage_get), \
> > FN(sk_storage_delete), \
> > FN(send_signal), \
> > - FN(tcp_gen_syncookie),
> > + FN(tcp_gen_syncookie), \
> > + FN(get_current_pidns_info),
> >
> > /* integer value in 'imm' field of BPF_CALL instruction selects which helper
> > * function eBPF program intends to call
> > @@ -3604,4 +3627,10 @@ struct bpf_sockopt {
> > __s32 retval;
> > };
> >
> > +struct bpf_pidns_info {
> > + __u32 dev;
>
> Please add a comment for dev for how device major and minor number are
> derived. User space gets device major and minor number, they need to
> compare to the corresponding major/minor numbers returned by this helper.
>
> > + __u32 nsid;
> > + __u32 tgid;
> > + __u32 pid;
> > +};
> > #endif /* _UAPI__LINUX_BPF_H__ */
> > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > index 8191a7db2777..3159f2a0188c 100644
> > --- a/kernel/bpf/core.c
> > +++ b/kernel/bpf/core.c
> > @@ -2038,6 +2038,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
> > const struct bpf_func_proto bpf_get_current_comm_proto __weak;
> > const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
> > const struct bpf_func_proto bpf_get_local_storage_proto __weak;
> > +const struct bpf_func_proto bpf_get_current_pidns_info __weak;
> >
> > const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
> > {
> > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> > index 5e28718928ca..41fbf1f28a48 100644
> > --- a/kernel/bpf/helpers.c
> > +++ b/kernel/bpf/helpers.c
> > @@ -11,6 +11,12 @@
> > #include <linux/uidgid.h>
> > #include <linux/filter.h>
> > #include <linux/ctype.h>
> > +#include <linux/pid_namespace.h>
> > +#include <linux/major.h>
> > +#include <linux/stat.h>
> > +#include <linux/namei.h>
> > +#include <linux/version.h>
> > +
> >
> > #include "../../lib/kstrtox.h"
> >
> > @@ -312,6 +318,64 @@ void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
> > preempt_enable();
> > }
> >
> > +BPF_CALL_2(bpf_get_current_pidns_info, struct bpf_pidns_info *, pidns_info, u32,
> > + size)
> > +{
> > + const char *pidns_path = "/proc/self/ns/pid";
> > + struct pid_namespace *pidns = NULL;
> > + struct filename *tmp = NULL;
>
> tmp => fname
>
> > + struct inode *inode;
> > + struct path kp;
> > + pid_t tgid = 0;
> > + pid_t pid = 0;
> > + int ret;
> > + int len;
> > +
> > + if (unlikely(size != sizeof(struct bpf_pidns_info)))
> > + return -EINVAL;
>
> Please put an empty line. As a general rule for readability,
> put an empty line if control flow is interrupted, e.g., by
> "return", "break" or "continue". At least this is what
> I saw most in bpf mailing list.
>
> > + pidns = task_active_pid_ns(current);
> > + if (unlikely(!pidns))
> > + goto clear;
>
> An empty line. Also, there is nothing to clear.
> I prefer an error code -ENOENT.
>
> You can set
> ret = -EINVAL;
> here
>
> > + pidns_info->nsid = pidns->ns.inum;
> > + pid = task_pid_nr_ns(current, pidns);
> > + if (unlikely(!pid))
> > + goto clear;
>
> An empty line.
>
> > + tgid = task_tgid_nr_ns(current, pidns);
> > + if (unlikely(!tgid))
> > + goto clear;
>
> An empty line.
>
> > + pidns_info->tgid = (u32) tgid;
> > + pidns_info->pid = (u32) pid;
>
> Different functionality, an empty line.
>
> > + tmp = kmem_cache_alloc(names_cachep, GFP_ATOMIC);
> > + if (unlikely(!tmp)) {
> > + memset((void *)pidns_info, 0, (size_t) size);
> > + return -ENOMEM;
>
> ret = -ENOMEM;
> goto clear;
>
> > + }
>
> An empty line.
>
> > + len = strlen(pidns_path) + 1;
> > + memcpy((char *)tmp->name, pidns_path, len);
> > + tmp->uptr = NULL;
> > + tmp->aname = NULL;
> > + tmp->refcnt = 1;
> > + ret = filename_lookup(AT_FDCWD, tmp, 0, &kp, NULL);
> Adding below to free kmem cache memory
> kmem_cache_free(names_cachep, fname);
>
> In the above, we checked task_active_pid_ns().
> If not returning NULL, we have a valid pid ns. So the above
> filename_lookup should not go wrong. We can still keep
> the error checking though.
>
> > + if (ret) {
> > + memset((void *)pidns_info, 0, (size_t) size);
> > + return ret;
>
> goto clear;
>
> > + }
>
> An empty line.
>
> > + inode = d_backing_inode(kp.dentry);
> > + pidns_info->dev = inode->i_sb->s_dev;
> > + return 0;
>
> An empty line.
>
> > +clear > + memset((void *)pidns_info, 0, (size_t) size);
> > + return -EINVAL;
> > +}
> > +
> > +const struct bpf_func_proto bpf_get_current_pidns_info_proto = {
> > + .func = bpf_get_current_pidns_info,
> > + .gpl_only = false,
> > + .ret_type = RET_INTEGER,
> > + .arg1_type = ARG_PTR_TO_UNINIT_MEM,
> > + .arg2_type = ARG_CONST_SIZE,
> > +};
> > +
> > #ifdef CONFIG_CGROUPS
> > BPF_CALL_0(bpf_get_current_cgroup_id)
> > {
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index ca1255d14576..5e1dc22765a5 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -709,6 +709,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> > #endif
> > case BPF_FUNC_send_signal:
> > return &bpf_send_signal_proto;
> > + case BPF_FUNC_get_current_pidns_info:
> > + return &bpf_get_current_pidns_info_proto;
> > default:
> > return NULL;
> > }
> >
^ permalink raw reply
* Re: [PATCH] bpfilter/verifier: add include guard to tnum.h
From: Daniel Borkmann @ 2019-08-20 15:10 UTC (permalink / raw)
To: Masahiro Yamada, Alexei Starovoitov, Martin KaFai Lau, Song Liu,
Yonghong Song, netdev, bpf
Cc: linux-kernel
In-Reply-To: <20190819161035.21826-1-yamada.masahiro@socionext.com>
On 8/19/19 6:10 PM, Masahiro Yamada wrote:
> Add a header include guard just in case.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH] test_bpf: Fix a new clang warning about xor-ing two numbers
From: Daniel Borkmann @ 2019-08-20 15:11 UTC (permalink / raw)
To: Nathan Chancellor, Alexei Starovoitov
Cc: Martin KaFai Lau, Song Liu, Yonghong Song, netdev, bpf,
linux-kernel, clang-built-linux
In-Reply-To: <20190819043419.68223-1-natechancellor@gmail.com>
On 8/19/19 6:34 AM, Nathan Chancellor wrote:
> r369217 in clang added a new warning about potential misuse of the xor
> operator as an exponentiation operator:
>
> ../lib/test_bpf.c:870:13: warning: result of '10 ^ 300' is 294; did you
> mean '1e300'? [-Wxor-used-as-pow]
> { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } },
> ~~~^~~~~
> 1e300
> ../lib/test_bpf.c:870:13: note: replace expression with '0xA ^ 300' to
> silence this warning
> ../lib/test_bpf.c:870:31: warning: result of '10 ^ 300' is 294; did you
> mean '1e300'? [-Wxor-used-as-pow]
> { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } },
> ~~~^~~~~
> 1e300
> ../lib/test_bpf.c:870:31: note: replace expression with '0xA ^ 300' to
> silence this warning
>
> The commit link for this new warning has some good logic behind wanting
> to add it but this instance appears to be a false positive. Adopt its
> suggestion to silence the warning but not change the code. According to
> the differential review link in the clang commit, GCC may eventually
> adopt this warning as well.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/643
> Link: https://github.com/llvm/llvm-project/commit/920890e26812f808a74c60ebc14cc636dac661c1
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH bpf 1/1] xdp: unpin xdp umem pages in error path
From: Daniel Borkmann @ 2019-08-20 15:12 UTC (permalink / raw)
To: Ivan Khoronzhuk, bjorn.topel
Cc: magnus.karlsson, jonathan.lemon, davem, ast, jakub.kicinski, hawk,
john.fastabend, netdev, bpf, linux-kernel
In-Reply-To: <20190815205635.6536-1-ivan.khoronzhuk@linaro.org>
On 8/15/19 10:56 PM, Ivan Khoronzhuk wrote:
> Fix mem leak caused by missed unpin routine for umem pages.
> Fixes: 8aef7340ae9695 ("commit xsk: introduce xdp_umem_page")
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Applied & fixed up 'Fixes:' tag, thanks.
^ permalink raw reply
* [PATCH net] ixgbe: fix double clean of tx descriptors with xdp
From: Ilya Maximets @ 2019-08-20 15:16 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, bpf, David S. Miller, Björn Töpel,
Magnus Karlsson, Jakub Kicinski, Alexei Starovoitov,
Daniel Borkmann, Jeff Kirsher, intel-wired-lan, Eelco Chaudron,
William Tu, Ilya Maximets
In-Reply-To: <CGME20190820151644eucas1p179d6d1da42bb6be0aad8f58ac46624ce@eucas1p1.samsung.com>
Tx code doesn't clear the descriptor status after cleaning.
So, if the budget is larger than number of used elems in a ring, some
descriptors will be accounted twice and xsk_umem_complete_tx will move
prod_tail far beyond the prod_head breaking the comletion queue ring.
Fix that by limiting the number of descriptors to clean by the number
of used descriptors in the tx ring.
Fixes: 8221c5eba8c1 ("ixgbe: add AF_XDP zero-copy Tx support")
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
Not tested yet because of lack of available hardware.
So, testing is very welcome.
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 10 ++++++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 12 +-----------
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 6 ++++--
3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 39e73ad60352..0befcef46e80 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -512,6 +512,16 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
}
+static inline u64 ixgbe_desc_used(struct ixgbe_ring *ring)
+{
+ unsigned int head, tail;
+
+ head = ring->next_to_clean;
+ tail = ring->next_to_use;
+
+ return ((head <= tail) ? tail : tail + ring->count) - head;
+}
+
#define IXGBE_RX_DESC(R, i) \
(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC(R, i) \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 7882148abb43..d417237857d8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1012,21 +1012,11 @@ static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring)
return ring->stats.packets;
}
-static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring)
-{
- unsigned int head, tail;
-
- head = ring->next_to_clean;
- tail = ring->next_to_use;
-
- return ((head <= tail) ? tail : tail + ring->count) - head;
-}
-
static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
{
u32 tx_done = ixgbe_get_tx_completed(tx_ring);
u32 tx_done_old = tx_ring->tx_stats.tx_done_old;
- u32 tx_pending = ixgbe_get_tx_pending(tx_ring);
+ u32 tx_pending = ixgbe_desc_used(tx_ring);
clear_check_for_tx_hang(tx_ring);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
index 6b609553329f..7702efed356a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -637,6 +637,7 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
u32 i = tx_ring->next_to_clean, xsk_frames = 0;
unsigned int budget = q_vector->tx.work_limit;
struct xdp_umem *umem = tx_ring->xsk_umem;
+ u32 used_descs = ixgbe_desc_used(tx_ring);
union ixgbe_adv_tx_desc *tx_desc;
struct ixgbe_tx_buffer *tx_bi;
bool xmit_done;
@@ -645,7 +646,7 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
tx_desc = IXGBE_TX_DESC(tx_ring, i);
i -= tx_ring->count;
- do {
+ while (likely(budget && used_descs)) {
if (!(tx_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
break;
@@ -673,7 +674,8 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
/* update budget accounting */
budget--;
- } while (likely(budget));
+ used_descs--;
+ }
i += tx_ring->count;
tx_ring->next_to_clean = i;
--
2.17.1
^ permalink raw reply related
* [PATCH] net: Fix detection for IPv4 duplicate address.
From: Dongxu Liu @ 2019-08-20 15:19 UTC (permalink / raw)
To: davem, kuznet, yoshfuji, netdev, linux-kernel
The network sends an ARP REQUEST packet to determine
whether there is a host with the same IP.
The source IP address of the packet is 0.
However, Windows may also send the source IP address
to determine, then the source IP address is equal to
the destination IP address.
Signed-off-by: Dongxu Liu <liudongxu3@huawei.com>
---
net/ipv4/arp.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 05eb42f..944f8e8 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -800,8 +800,11 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
iptunnel_metadata_reply(skb_metadata_dst(skb),
GFP_ATOMIC);
- /* Special case: IPv4 duplicate address detection packet (RFC2131) */
- if (sip == 0) {
+/* Special case: IPv4 duplicate address detection packet (RFC2131).
+ * Linux usually sends zero to detect duplication, and windows may
+ * send a same ip (not zero, sip equal to tip) to do this detection.
+ */
+ if (sip == 0 || sip == tip) {
if (arp->ar_op == htons(ARPOP_REQUEST) &&
inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL &&
!arp_ignore(in_dev, sip, tip))
--
2.12.3
^ permalink raw reply related
* Re: [PATCH net-next v3 2/4] net: mdio: add PTP offset compensation to mdiobus_write_sts
From: Andrew Lunn @ 2019-08-20 15:23 UTC (permalink / raw)
To: Miroslav Lichvar
Cc: Hubert Feurstein, netdev, lkml, Richard Cochran, Florian Fainelli,
Heiner Kallweit, Vladimir Oltean, David S. Miller
In-Reply-To: <20190820142537.GL891@localhost>
> - take a second "post" system timestamp after the completion
For this hardware, completion is an interrupt, which has a lot of
jitter on it. But this hardware is odd, in that it uses an
interrupt. Every other MDIO bus controller uses polled IO, with an
mdelay(10) or similar between each poll. So the jitter is going to be
much larger.
Even though the FEC is special with its interrupt completion, i would
like to see the solution being reasonably generic so that others can
copy it into other MDIO bus drivers. That is what is nice about taking
the time stamp around the write which triggers the bus transaction. It
is independent of interrupt or polled, and should mean about the same
thing for different vendors hardware.
Andrew
^ 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