* [PATCH V2 4/5] RDMA/cxgb4: Fix LE hash collision bug for passive open connection
From: Vipul Pandya @ 2012-11-30 12:09 UTC (permalink / raw)
To: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
Cc: roland-BHEL68pLQRGGvPXPguhicg, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
divy-ut6Up61K2wZBDgjK7y7TUQ, dm-ut6Up61K2wZBDgjK7y7TUQ,
kumaras-ut6Up61K2wZBDgjK7y7TUQ,
swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
abhishek-ut6Up61K2wZBDgjK7y7TUQ, Vipul Pandya
In-Reply-To: <1354277370-8727-1-git-send-email-vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
It establishes passive open connection through firmware work request. Passive
open connection will go through this path as now instead of listening server we
create a server filter which will redirect the incoming SYN packet to the
offload queue. After this driver tries to establish the connection using
firmware work request.
Signed-off-by: Vipul Pandya <vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---
V2: Changed commenting style from kernel-doc format('/**') to normal
drivers/infiniband/hw/cxgb4/cm.c | 411 ++++++++++++++++++++---
drivers/infiniband/hw/cxgb4/device.c | 85 +++++-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 9 +
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 46 +++
4 files changed, 496 insertions(+), 55 deletions(-)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 4878704..2ac6a2c 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -38,10 +38,12 @@
#include <linux/inetdevice.h>
#include <linux/ip.h>
#include <linux/tcp.h>
+#include <linux/if_vlan.h>
#include <net/neighbour.h>
#include <net/netevent.h>
#include <net/route.h>
+#include <net/tcp.h>
#include "iw_cxgb4.h"
@@ -1569,13 +1571,14 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
struct c4iw_listen_ep *ep = lookup_stid(t, stid);
if (!ep) {
- printk(KERN_ERR MOD "stid %d lookup failure!\n", stid);
- return 0;
+ PDBG("%s stid %d lookup failure!\n", __func__, stid);
+ goto out;
}
PDBG("%s ep %p status %d error %d\n", __func__, ep,
rpl->status, status2errno(rpl->status));
c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
+out:
return 0;
}
@@ -1779,15 +1782,23 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
unsigned int hwtid = GET_TID(req);
struct dst_entry *dst;
struct rtable *rt;
- __be32 local_ip, peer_ip;
+ __be32 local_ip, peer_ip = 0;
__be16 local_port, peer_port;
int err;
+ u16 peer_mss = ntohs(req->tcpopt.mss);
parent_ep = lookup_stid(t, stid);
- PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid);
-
+ if (!parent_ep) {
+ PDBG("%s connect request on invalid stid %d\n", __func__, stid);
+ goto reject;
+ }
get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port);
+ PDBG("%s parent ep %p hwtid %u laddr 0x%x raddr 0x%x lport %d " \
+ "rport %d peer_mss %d\n", __func__, parent_ep, hwtid,
+ ntohl(local_ip), ntohl(peer_ip), ntohs(local_port),
+ ntohs(peer_port), peer_mss);
+
if (state_read(&parent_ep->com) != LISTEN) {
printk(KERN_ERR "%s - listening ep not in LISTEN\n",
__func__);
@@ -1821,6 +1832,9 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
goto reject;
}
+ if (peer_mss && child_ep->mtu > (peer_mss + 40))
+ child_ep->mtu = peer_mss + 40;
+
state_set(&child_ep->com, CONNECTING);
child_ep->com.dev = dev;
child_ep->com.cm_id = NULL;
@@ -1861,6 +1875,9 @@ static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb)
ep->snd_seq = be32_to_cpu(req->snd_isn);
ep->rcv_seq = be32_to_cpu(req->rcv_isn);
+ PDBG("%s ep %p hwtid %u tcp_opt 0x%02x\n", __func__, ep, tid,
+ ntohs(req->tcp_opt));
+
set_emss(ep, ntohs(req->tcp_opt));
dst_confirm(ep->dst);
@@ -2478,7 +2495,6 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
struct c4iw_listen_ep *ep;
-
might_sleep();
ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
@@ -2497,30 +2513,49 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
/*
* Allocate a server TID.
*/
- ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep);
+ if (dev->rdev.lldi.enable_fw_ofld_conn)
+ ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids, PF_INET, ep);
+ else
+ ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep);
+
if (ep->stid == -1) {
printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__);
err = -ENOMEM;
goto fail2;
}
-
state_set(&ep->com, LISTEN);
- c4iw_init_wr_wait(&ep->com.wr_wait);
- err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid,
- ep->com.local_addr.sin_addr.s_addr,
- ep->com.local_addr.sin_port,
- ep->com.dev->rdev.lldi.rxq_ids[0]);
- if (err)
- goto fail3;
-
- /* wait for pass_open_rpl */
- err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,
- __func__);
+ if (dev->rdev.lldi.enable_fw_ofld_conn) {
+ do {
+ err = cxgb4_create_server_filter(
+ ep->com.dev->rdev.lldi.ports[0], ep->stid,
+ ep->com.local_addr.sin_addr.s_addr,
+ ep->com.local_addr.sin_port,
+ ep->com.dev->rdev.lldi.rxq_ids[0]);
+ if (err == -EBUSY) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(usecs_to_jiffies(100));
+ }
+ } while (err == -EBUSY);
+ } else {
+ c4iw_init_wr_wait(&ep->com.wr_wait);
+ err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0],
+ ep->stid, ep->com.local_addr.sin_addr.s_addr,
+ ep->com.local_addr.sin_port,
+ ep->com.dev->rdev.lldi.rxq_ids[0]);
+ if (!err)
+ err = c4iw_wait_for_reply(&ep->com.dev->rdev,
+ &ep->com.wr_wait,
+ 0, 0, __func__);
+ }
if (!err) {
cm_id->provider_data = ep;
goto out;
}
-fail3:
+ pr_err("%s cxgb4_create_server/filter failed err %d " \
+ "stid %d laddr %08x lport %d\n", \
+ __func__, err, ep->stid,
+ ntohl(ep->com.local_addr.sin_addr.s_addr),
+ ntohs(ep->com.local_addr.sin_port));
cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);
fail2:
cm_id->rem_ref(cm_id);
@@ -2539,12 +2574,18 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id)
might_sleep();
state_set(&ep->com, DEAD);
- c4iw_init_wr_wait(&ep->com.wr_wait);
- err = listen_stop(ep);
- if (err)
- goto done;
- err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,
- __func__);
+ if (ep->com.dev->rdev.lldi.enable_fw_ofld_conn) {
+ err = cxgb4_remove_server_filter(
+ ep->com.dev->rdev.lldi.ports[0], ep->stid,
+ ep->com.dev->rdev.lldi.rxq_ids[0], 0);
+ } else {
+ c4iw_init_wr_wait(&ep->com.wr_wait);
+ err = listen_stop(ep);
+ if (err)
+ goto done;
+ err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait,
+ 0, 0, __func__);
+ }
cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);
done:
cm_id->rem_ref(cm_id);
@@ -2621,10 +2662,298 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
return ret;
}
-static int async_event(struct c4iw_dev *dev, struct sk_buff *skb)
+static void active_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
+ struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
+{
+ struct c4iw_ep *ep;
+
+ ep = (struct c4iw_ep *)lookup_atid(dev->rdev.lldi.tids, req->tid);
+ if (!ep)
+ return;
+
+ switch (req->retval) {
+ case FW_ENOMEM:
+ case FW_EADDRINUSE:
+ PDBG("%s ofld conn wr ret %d\n", __func__, req->retval);
+ break;
+ default:
+ pr_info("%s unexpected ofld conn wr retval %d\n",
+ __func__, req->retval);
+ break;
+ }
+ connect_reply_upcall(ep, status2errno(req->retval));
+}
+
+static void passive_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
+ struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
+{
+ struct sk_buff *rpl_skb;
+ struct cpl_pass_accept_req *cpl;
+ int ret;
+
+ rpl_skb = (struct sk_buff *)cpu_to_be64(req->cookie);
+ BUG_ON(!rpl_skb);
+ if (req->retval) {
+ PDBG("%s passive open failure %d\n", __func__, req->retval);
+ kfree_skb(rpl_skb);
+ } else {
+ cpl = (struct cpl_pass_accept_req *)cplhdr(rpl_skb);
+ OPCODE_TID(cpl) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ,
+ htonl(req->tid)));
+ ret = pass_accept_req(dev, rpl_skb);
+ if (!ret)
+ kfree_skb(rpl_skb);
+ }
+ return;
+}
+
+static int deferred_fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
{
struct cpl_fw6_msg *rpl = cplhdr(skb);
- c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]);
+ struct cpl_fw6_msg_ofld_connection_wr_rpl *req;
+
+ switch (rpl->type) {
+ case FW6_TYPE_CQE:
+ c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]);
+ break;
+ case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
+ req = (struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data;
+ switch (req->t_state) {
+ case TCP_SYN_SENT:
+ active_ofld_conn_reply(dev, skb, req);
+ break;
+ case TCP_SYN_RECV:
+ passive_ofld_conn_reply(dev, skb, req);
+ break;
+ default:
+ pr_err("%s unexpected ofld conn wr state %d\n",
+ __func__, req->t_state);
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos)
+{
+ u32 l2info;
+ u16 vlantag, len, hdr_len;
+ u8 intf;
+ struct cpl_rx_pkt *cpl = cplhdr(skb);
+ struct cpl_pass_accept_req *req;
+ struct tcp_options_received tmp_opt;
+
+ /* Store values from cpl_rx_pkt in temporary location. */
+ vlantag = cpl->vlan;
+ len = cpl->len;
+ l2info = cpl->l2info;
+ hdr_len = cpl->hdr_len;
+ intf = cpl->iff;
+
+ __skb_pull(skb, sizeof(*req) + sizeof(struct rss_header));
+
+ /* We need to parse the TCP options from SYN packet.
+ * to generate cpl_pass_accept_req.
+ */
+ memset(&tmp_opt, 0, sizeof(tmp_opt));
+ tcp_clear_options(&tmp_opt);
+ tcp_parse_options(skb, &tmp_opt, 0, 0, NULL);
+
+ req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req));
+ memset(req, 0, sizeof(*req));
+ req->l2info = cpu_to_be16(V_SYN_INTF(intf) |
+ V_SYN_MAC_IDX(G_RX_MACIDX(htonl(l2info))) |
+ F_SYN_XACT_MATCH);
+ req->hdr_len = cpu_to_be32(V_SYN_RX_CHAN(G_RX_CHAN(htonl(l2info))) |
+ V_TCP_HDR_LEN(G_RX_TCPHDR_LEN(htons(hdr_len))) |
+ V_IP_HDR_LEN(G_RX_IPHDR_LEN(htons(hdr_len))) |
+ V_ETH_HDR_LEN(G_RX_ETHHDR_LEN(htonl(l2info))));
+ req->vlan = vlantag;
+ req->len = len;
+ req->tos_stid = cpu_to_be32(PASS_OPEN_TID(stid) |
+ PASS_OPEN_TOS(tos));
+ req->tcpopt.mss = htons(tmp_opt.mss_clamp);
+ if (tmp_opt.wscale_ok)
+ req->tcpopt.wsf = tmp_opt.snd_wscale;
+ req->tcpopt.tstamp = tmp_opt.saw_tstamp;
+ if (tmp_opt.sack_ok)
+ req->tcpopt.sack = 1;
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ, 0));
+ return;
+}
+
+static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb,
+ __be32 laddr, __be16 lport,
+ __be32 raddr, __be16 rport,
+ u32 rcv_isn, u32 filter, u16 window,
+ u32 rss_qid, u8 port_id)
+{
+ struct sk_buff *req_skb;
+ struct fw_ofld_connection_wr *req;
+ struct cpl_pass_accept_req *cpl = cplhdr(skb);
+
+ req_skb = alloc_skb(sizeof(struct fw_ofld_connection_wr), GFP_KERNEL);
+ req = (struct fw_ofld_connection_wr *)__skb_put(req_skb, sizeof(*req));
+ memset(req, 0, sizeof(*req));
+ req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL(1));
+ req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
+ req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL);
+ req->le.filter = filter;
+ req->le.lport = lport;
+ req->le.pport = rport;
+ req->le.u.ipv4.lip = laddr;
+ req->le.u.ipv4.pip = raddr;
+ req->tcb.rcv_nxt = htonl(rcv_isn + 1);
+ req->tcb.rcv_adv = htons(window);
+ req->tcb.t_state_to_astid =
+ htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_RECV) |
+ V_FW_OFLD_CONNECTION_WR_RCV_SCALE(cpl->tcpopt.wsf) |
+ V_FW_OFLD_CONNECTION_WR_ASTID(
+ GET_PASS_OPEN_TID(ntohl(cpl->tos_stid))));
+
+ /*
+ * We store the qid in opt2 which will be used by the firmware
+ * to send us the wr response.
+ */
+ req->tcb.opt2 = htonl(V_RSS_QUEUE(rss_qid));
+
+ /*
+ * We initialize the MSS index in TCB to 0xF.
+ * So that when driver sends cpl_pass_accept_rpl
+ * TCB picks up the correct value. If this was 0
+ * TP will ignore any value > 0 for MSS index.
+ */
+ req->tcb.opt0 = cpu_to_be64(V_MSS_IDX(0xF));
+ req->cookie = cpu_to_be64((u64)skb);
+
+ set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id);
+ cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb);
+}
+
+/*
+ * Handler for CPL_RX_PKT message. Need to handle cpl_rx_pkt
+ * messages when a filter is being used instead of server to
+ * redirect a syn packet. When packets hit filter they are redirected
+ * to the offload queue and driver tries to establish the connection
+ * using firmware work request.
+ */
+static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
+{
+ int stid;
+ unsigned int filter;
+ struct ethhdr *eh = NULL;
+ struct vlan_ethhdr *vlan_eh = NULL;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ struct rss_header *rss = (void *)skb->data;
+ struct cpl_rx_pkt *cpl = (void *)skb->data;
+ struct cpl_pass_accept_req *req = (void *)(rss + 1);
+ struct l2t_entry *e;
+ struct dst_entry *dst;
+ struct rtable *rt;
+ struct c4iw_ep *lep;
+ u16 window;
+ struct port_info *pi;
+ struct net_device *pdev;
+ u16 rss_qid;
+ int step;
+ u32 tx_chan;
+ struct neighbour *neigh;
+
+ /* Drop all non-SYN packets */
+ if (!(cpl->l2info & cpu_to_be32(F_RXF_SYN)))
+ goto reject;
+
+ /*
+ * Drop all packets which did not hit the filter.
+ * Unlikely to happen.
+ */
+ if (!(rss->filter_hit && rss->filter_tid))
+ goto reject;
+
+ /*
+ * Calculate the server tid from filter hit index from cpl_rx_pkt.
+ */
+ stid = cpu_to_be32(rss->hash_val) - dev->rdev.lldi.tids->sftid_base
+ + dev->rdev.lldi.tids->nstids;
+
+ lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid);
+ if (!lep) {
+ PDBG("%s connect request on invalid stid %d\n", __func__, stid);
+ goto reject;
+ }
+
+ if (G_RX_ETHHDR_LEN(ntohl(cpl->l2info)) == ETH_HLEN) {
+ eh = (struct ethhdr *)(req + 1);
+ iph = (struct iphdr *)(eh + 1);
+ } else {
+ vlan_eh = (struct vlan_ethhdr *)(req + 1);
+ iph = (struct iphdr *)(vlan_eh + 1);
+ skb->vlan_tci = ntohs(cpl->vlan);
+ }
+
+ if (iph->version != 0x4)
+ goto reject;
+
+ tcph = (struct tcphdr *)(iph + 1);
+ skb_set_network_header(skb, (void *)iph - (void *)rss);
+ skb_set_transport_header(skb, (void *)tcph - (void *)rss);
+ skb_get(skb);
+
+ PDBG("%s lip 0x%x lport %u pip 0x%x pport %u tos %d\n", __func__,
+ ntohl(iph->daddr), ntohs(tcph->dest), ntohl(iph->saddr),
+ ntohs(tcph->source), iph->tos);
+
+ rt = find_route(dev, iph->daddr, iph->saddr, tcph->dest, tcph->source,
+ iph->tos);
+ if (!rt) {
+ pr_err("%s - failed to find dst entry!\n",
+ __func__);
+ goto reject;
+ }
+ dst = &rt->dst;
+ neigh = dst_neigh_lookup_skb(dst, skb);
+
+ if (neigh->dev->flags & IFF_LOOPBACK) {
+ pdev = ip_dev_find(&init_net, iph->daddr);
+ e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
+ pdev, 0);
+ pi = (struct port_info *)netdev_priv(pdev);
+ tx_chan = cxgb4_port_chan(pdev);
+ dev_put(pdev);
+ } else {
+ e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
+ neigh->dev, 0);
+ pi = (struct port_info *)netdev_priv(neigh->dev);
+ tx_chan = cxgb4_port_chan(neigh->dev);
+ }
+ if (!e) {
+ pr_err("%s - failed to allocate l2t entry!\n",
+ __func__);
+ goto free_dst;
+ }
+
+ step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
+ rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step];
+ window = htons(tcph->window);
+
+ /* Calcuate filter portion for LE region. */
+ filter = cpu_to_be32(select_ntuple(dev, dst, e));
+
+ /*
+ * Synthesize the cpl_pass_accept_req. We have everything except the
+ * TID. Once firmware sends a reply with TID we update the TID field
+ * in cpl and pass it through the regular cpl_pass_accept_req path.
+ */
+ build_cpl_pass_accept_req(skb, stid, iph->tos);
+ send_fw_pass_open_req(dev, skb, iph->daddr, tcph->dest, iph->saddr,
+ tcph->source, ntohl(tcph->seq), filter, window,
+ rss_qid, pi->port_id);
+ cxgb4_l2t_release(e);
+free_dst:
+ dst_release(dst);
+reject:
return 0;
}
@@ -2647,7 +2976,8 @@ static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = {
[CPL_CLOSE_CON_RPL] = close_con_rpl,
[CPL_RDMA_TERMINATE] = terminate,
[CPL_FW4_ACK] = fw4_ack,
- [CPL_FW6_MSG] = async_event
+ [CPL_FW6_MSG] = deferred_fw6_msg,
+ [CPL_RX_PKT] = rx_pkt
};
static void process_timeout(struct c4iw_ep *ep)
@@ -2774,9 +3104,6 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
struct cpl_fw6_msg *rpl = cplhdr(skb);
struct c4iw_wr_wait *wr_waitp;
int ret;
- u8 opcode;
- struct cpl_fw6_msg_ofld_connection_wr_rpl *req;
- struct c4iw_ep *ep;
PDBG("%s type %u\n", __func__, rpl->type);
@@ -2790,23 +3117,8 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
kfree_skb(skb);
break;
case FW6_TYPE_CQE:
- sched(dev, skb);
- break;
case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
- opcode = *(const u8 *)rpl->data;
- if (opcode == FW_OFLD_CONNECTION_WR) {
- req =
- (struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data;
- if (req->t_state == TCP_SYN_SENT
- && (req->retval == FW_ENOMEM
- || req->retval == FW_EADDRINUSE)) {
- ep = (struct c4iw_ep *)
- lookup_atid(dev->rdev.lldi.tids,
- req->tid);
- c4iw_l2t_send(&dev->rdev, skb, ep->l2t);
- return 0;
- }
- }
+ sched(dev, skb);
break;
default:
printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__,
@@ -2868,7 +3180,8 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = {
[CPL_RDMA_TERMINATE] = sched,
[CPL_FW4_ACK] = sched,
[CPL_SET_TCB_RPL] = set_tcb_rpl,
- [CPL_FW6_MSG] = fw6_msg
+ [CPL_FW6_MSG] = fw6_msg,
+ [CPL_RX_PKT] = sched
};
int __init c4iw_cm_init(void)
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index cb4ecd7..6b5b3d1 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -279,6 +279,7 @@ static int stats_show(struct seq_file *seq, void *v)
seq_printf(seq, " DB State: %s Transitions %llu\n",
db_state_str[dev->db_state],
dev->rdev.stats.db_state_transitions);
+ seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full);
return 0;
}
@@ -577,14 +578,76 @@ out:
return ctx;
}
+static inline struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl,
+ const __be64 *rsp,
+ u32 pktshift)
+{
+ struct sk_buff *skb;
+
+ /*
+ * Allocate space for cpl_pass_accept_req which will be synthesized by
+ * driver. Once the driver synthesizes the request the skb will go
+ * through the regular cpl_pass_accept_req processing.
+ * The math here assumes sizeof cpl_pass_accept_req >= sizeof
+ * cpl_rx_pkt.
+ */
+ skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) +
+ sizeof(struct rss_header) - pktshift, GFP_ATOMIC);
+ if (unlikely(!skb))
+ return NULL;
+
+ __skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req) +
+ sizeof(struct rss_header) - pktshift);
+
+ /*
+ * This skb will contain:
+ * rss_header from the rspq descriptor (1 flit)
+ * cpl_rx_pkt struct from the rspq descriptor (2 flits)
+ * space for the difference between the size of an
+ * rx_pkt and pass_accept_req cpl (1 flit)
+ * the packet data from the gl
+ */
+ skb_copy_to_linear_data(skb, rsp, sizeof(struct cpl_pass_accept_req) +
+ sizeof(struct rss_header));
+ skb_copy_to_linear_data_offset(skb, sizeof(struct rss_header) +
+ sizeof(struct cpl_pass_accept_req),
+ gl->va + pktshift,
+ gl->tot_len - pktshift);
+ return skb;
+}
+
+static inline int recv_rx_pkt(struct c4iw_dev *dev, const struct pkt_gl *gl,
+ const __be64 *rsp)
+{
+ unsigned int opcode = *(u8 *)rsp;
+ struct sk_buff *skb;
+
+ if (opcode != CPL_RX_PKT)
+ goto out;
+
+ skb = copy_gl_to_skb_pkt(gl , rsp, dev->rdev.lldi.sge_pktshift);
+ if (skb == NULL)
+ goto out;
+
+ if (c4iw_handlers[opcode] == NULL) {
+ pr_info("%s no handler opcode 0x%x...\n", __func__,
+ opcode);
+ kfree_skb(skb);
+ goto out;
+ }
+ c4iw_handlers[opcode](dev, skb);
+ return 1;
+out:
+ return 0;
+}
+
static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,
const struct pkt_gl *gl)
{
struct uld_ctx *ctx = handle;
struct c4iw_dev *dev = ctx->dev;
struct sk_buff *skb;
- const struct cpl_act_establish *rpl;
- unsigned int opcode;
+ u8 opcode;
if (gl == NULL) {
/* omit RSS and rsp_ctrl at end of descriptor */
@@ -601,19 +664,29 @@ static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,
u32 qid = be32_to_cpu(rc->pldbuflen_qid);
c4iw_ev_handler(dev, qid);
return 0;
+ } else if (unlikely(*(u8 *)rsp != *(u8 *)gl->va)) {
+ if (recv_rx_pkt(dev, gl, rsp))
+ return 0;
+
+ pr_info("%s: unexpected FL contents at %p, " \
+ "RSS %#llx, FL %#llx, len %u\n",
+ pci_name(ctx->lldi.pdev), gl->va,
+ (unsigned long long)be64_to_cpu(*rsp),
+ (unsigned long long)be64_to_cpu(*(u64 *)gl->va),
+ gl->tot_len);
+
+ return 0;
} else {
skb = cxgb4_pktgl_to_skb(gl, 128, 128);
if (unlikely(!skb))
goto nomem;
}
- rpl = cplhdr(skb);
- opcode = rpl->ot.opcode;
-
+ opcode = *(u8 *)rsp;
if (c4iw_handlers[opcode])
c4iw_handlers[opcode](dev, skb);
else
- printk(KERN_INFO "%s no handler opcode 0x%x...\n", __func__,
+ pr_info("%s no handler opcode 0x%x...\n", __func__,
opcode);
return 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index f55386b..1a26e3f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3326,6 +3326,10 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
adap = netdev2adap(dev);
+ /* Adjust stid to correct filter index */
+ stid -= adap->tids.nstids;
+ stid += adap->tids.nftids;
+
/* Check to make sure the filter requested is writable ...
*/
f = &adap->tids.ftid_tab[stid];
@@ -3374,6 +3378,11 @@ int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
struct adapter *adap;
adap = netdev2adap(dev);
+
+ /* Adjust stid to correct filter index */
+ stid -= adap->tids.nstids;
+ stid += adap->tids.nftids;
+
f = &adap->tids.ftid_tab[stid];
/* Unlock the filter */
f->locked = 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index 5b51c01..1179616 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -199,6 +199,18 @@ struct work_request_hdr {
#define WR_HDR struct work_request_hdr wr
+/* option 0 fields */
+#define S_MSS_IDX 60
+#define M_MSS_IDX 0xF
+#define V_MSS_IDX(x) ((__u64)(x) << S_MSS_IDX)
+#define G_MSS_IDX(x) (((x) >> S_MSS_IDX) & M_MSS_IDX)
+
+/* option 2 fields */
+#define S_RSS_QUEUE 0
+#define M_RSS_QUEUE 0x3FF
+#define V_RSS_QUEUE(x) ((x) << S_RSS_QUEUE)
+#define G_RSS_QUEUE(x) (((x) >> S_RSS_QUEUE) & M_RSS_QUEUE)
+
struct cpl_pass_open_req {
WR_HDR;
union opcode_tid ot;
@@ -300,6 +312,9 @@ struct cpl_pass_establish {
union opcode_tid ot;
__be32 rsvd;
__be32 tos_stid;
+#define PASS_OPEN_TID(x) ((x) << 0)
+#define PASS_OPEN_TOS(x) ((x) << 24)
+#define GET_PASS_OPEN_TID(x) (((x) >> 0) & 0xFFFFFF)
#define GET_POPEN_TID(x) ((x) & 0xffffff)
#define GET_POPEN_TOS(x) (((x) >> 24) & 0xff)
__be16 mac_idx;
@@ -545,6 +560,37 @@ struct cpl_rx_pkt {
__be16 err_vec;
};
+/* rx_pkt.l2info fields */
+#define S_RX_ETHHDR_LEN 0
+#define M_RX_ETHHDR_LEN 0x1F
+#define V_RX_ETHHDR_LEN(x) ((x) << S_RX_ETHHDR_LEN)
+#define G_RX_ETHHDR_LEN(x) (((x) >> S_RX_ETHHDR_LEN) & M_RX_ETHHDR_LEN)
+
+#define S_RX_MACIDX 8
+#define M_RX_MACIDX 0x1FF
+#define V_RX_MACIDX(x) ((x) << S_RX_MACIDX)
+#define G_RX_MACIDX(x) (((x) >> S_RX_MACIDX) & M_RX_MACIDX)
+
+#define S_RXF_SYN 21
+#define V_RXF_SYN(x) ((x) << S_RXF_SYN)
+#define F_RXF_SYN V_RXF_SYN(1U)
+
+#define S_RX_CHAN 28
+#define M_RX_CHAN 0xF
+#define V_RX_CHAN(x) ((x) << S_RX_CHAN)
+#define G_RX_CHAN(x) (((x) >> S_RX_CHAN) & M_RX_CHAN)
+
+/* rx_pkt.hdr_len fields */
+#define S_RX_TCPHDR_LEN 0
+#define M_RX_TCPHDR_LEN 0x3F
+#define V_RX_TCPHDR_LEN(x) ((x) << S_RX_TCPHDR_LEN)
+#define G_RX_TCPHDR_LEN(x) (((x) >> S_RX_TCPHDR_LEN) & M_RX_TCPHDR_LEN)
+
+#define S_RX_IPHDR_LEN 6
+#define M_RX_IPHDR_LEN 0x3FF
+#define V_RX_IPHDR_LEN(x) ((x) << S_RX_IPHDR_LEN)
+#define G_RX_IPHDR_LEN(x) (((x) >> S_RX_IPHDR_LEN) & M_RX_IPHDR_LEN)
+
struct cpl_trace_pkt {
u8 opcode;
u8 intf;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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 related
* Re: [PATCH v2 3/3] pppoatm: protect against freeing of vcc
From: David Woodhouse @ 2012-11-30 12:10 UTC (permalink / raw)
To: Krzysztof Mazur
Cc: Chas Williams (CONTRACTOR), David Laight, davem, netdev,
linux-kernel, nathan
In-Reply-To: <20121130095354.GA15126@shrek.podlesie.net>
[-- Attachment #1: Type: text/plain, Size: 2554 bytes --]
On Fri, 2012-11-30 at 10:53 +0100, Krzysztof Mazur wrote:
> On Fri, Nov 30, 2012 at 08:25:22AM +0000, David Woodhouse wrote:
> > On Fri, 2012-11-30 at 01:57 +0000, David Woodhouse wrote:
> > > I think it's actually fixed for pppoatm by the bh_lock_sock() and the
> > > sock_owned_by_user() check. As soon as vcc_release() calls lock_sock(),
> > > pppoatm stops accepting packets.
> > >
> > > It should be simple enough to do the same in br2684.
> >
> > Um... but now I come to look at it... Krzysztof, doesn't your 'pppoatm:
> > take ATM socket lock in pppoatm_send()' patch actually *break* the case
> > of sending via vcc_sendmsg()?
>
> no,
... oops, sorry. My sleep-deprived brain thought that we were calling
pppoatm_send() *from* vcc_sendmsg() with the lock held. But of course
we're not; we're calling directly into the driver. So that's OK.
In that case I think we're fine. I'll just do the same thing in
br2684_push(), fix up the comment you just corrected, and we're all
good.
> I think that the current order is good, now we have:
>
> 1. stop_sending_fames to protocol
> now TX is shut down
> (currently done by
> set_bit(ATM_VF_CLOSE, &vcc->flags);
> clear_bit(ATM_VF_READY, &vcc->flags);
> )
Right, with the caveat the the socket lock is required for
synchronisation on this. But that's OK. Or we *could* perhaps introduce
an explicit call into the protocol for it, if we really wanted. But I'm
inclined not to.
> 2. close_device to device
> now RX is shut down
> 3. device_was_closed to protocol
> ugly push(NULL), but we can add some other callback.
> we also can do:
>
> 1. disable RX to device
> now RX is shut down
> 2. detach to protocol
> now TX is shut down
> (now protocol can fully detach because RX is disabled)
Careful. You have to flush the TX packets which are currently in-flight.
It's not sufficient just to stop sending any more. And you have to do it
*before* the data structures are torn down.
> 3. close_device to device
> (device is not used anymore)
Really, what we're saying is that *one* of the driver or protocol close
functions needs to be split, and we need to do DPD or PDP. Since the
device driver *can* abort/flush the TX queue and also any pending RX
being handled by a tasklet, I think it makes most sense to keep it in
the middle, with the protocol being handled first and last... which is
the current order, as long as we consider setting ATM_VF_CLOSE to be the
first part.
--
dwmw2
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]
^ permalink raw reply
* [PATCH] sctp: verify length provided in heartbeat information parameter
From: Thomas Graf @ 2012-11-30 12:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-sctp
If the variable parameter length provided in the mandatory
heartbeat information parameter exceeds the calculated payload
length the packet has been corrupted. Reply with a parameter
length protocol violation message.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
net/sctp/sm_statefuns.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b6adef8..e92079d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -1055,6 +1055,7 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
void *arg,
sctp_cmd_seq_t *commands)
{
+ sctp_paramhdr_t *param_hdr;
struct sctp_chunk *chunk = arg;
struct sctp_chunk *reply;
size_t paylen = 0;
@@ -1072,12 +1073,17 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
* Information field copied from the received HEARTBEAT chunk.
*/
chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
+ param_hdr = (sctp_paramhdr_t *) chunk->subh.hb_hdr;
paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
+
+ if (ntohs(param_hdr->length) > paylen)
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
+ param_hdr, commands);
+
if (!pskb_pull(chunk->skb, paylen))
goto nomem;
- reply = sctp_make_heartbeat_ack(asoc, chunk,
- chunk->subh.hb_hdr, paylen);
+ reply = sctp_make_heartbeat_ack(asoc, chunk, param_hdr, paylen);
if (!reply)
goto nomem;
^ permalink raw reply related
* Re: [PATCH] net: ICMPv6 packets transmitted on wrong interface if nfmark is mangled
From: Dries De Winter @ 2012-11-30 12:29 UTC (permalink / raw)
To: David Miller; +Cc: pablo, kaber, netdev, netfilter-devel
In-Reply-To: <20121128.183037.1780631404801131036.davem@davemloft.net>
2012/11/29 David Miller <davem@davemloft.net>:
> From: Dries De Winter <dries.dewinter@gmail.com>
> Date: Wed, 28 Nov 2012 10:09:55 +0100 (CET)
>
>> I propose a patch which allows to mark a dst_entry as "non-reroutable".
>> icmp6_dst_alloc() (used by ndisc and MLD implementation) will always mark
>> the
>> allocated dst_entry as such. A check is added to netfilter (IPv6-only) so
>> packets heading for a non-reroutable destination are never rerouted.
>
> What about addrconf_dst_alloc()? Shouldn't it have this new flag set
> as well?
I don't think so. I'm not sure if I understand all of IPv6 routing
correctly, but it looks like dst entries allocated by
addrconf_dst_alloc() are added to the routing table pretty much like
normal routes and skbuffs get assigned such dst entries by normal rule
lookup / route lookup.
If an skbuff got assigned such a dst entry by normal routing in the
first place, and the changes done by the mangle table don't affect
routing (e.g. skb->mark changed but no policy based routing), I guess
that rerouting the packet will get you there too. In the meantime, by
not specifying DST_NOREROUTE for such destinations, you don't lose the
capability to mangle a packet so it should really be routed
differently.
> Regardless of the answer to that question, it should be explained
> in the commit message.
Should I post a new patch email including this comment?
Regards,
Dries.
^ permalink raw reply
* Re: [net-next PATCH V2 8/9] net: frag queue locking per hash bucket
From: Jesper Dangaard Brouer @ 2012-11-30 12:55 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, Florian Westphal, netdev, Pablo Neira Ayuso,
Thomas Graf, Cong Wang, Patrick McHardy, Paul E. McKenney,
Herbert Xu
In-Reply-To: <1354208920.14302.1907.camel@edumazet-glaptop>
On Thu, 2012-11-29 at 09:08 -0800, Eric Dumazet wrote:
> So we still have this huge contention on the reader-writer lock cache
> line...
> I would just remove it. (And remove hash rebuild, or make it RCU
> compatible )
I vote for removing the rebuild feature. It really doesn't make sense
to protect a 256Kb memory (using) hash, with very short lived elements,
against hash collision attacks, every 10 minutes. (Especially as we saw
a 7 GBit/s performance improvement)
Making the hash RCU "compatible" is not going to work, because the
elements are too short lived, thus we cannot free them fast enough
(call_rcu stuff). (I actually did the RCU implementation, to realize
this...)
^ permalink raw reply
* [PATCH] [trivial] wireless: mwifiex: Fix typo in wireless/mwifiex driver
From: Masanari Iida @ 2012-11-30 13:08 UTC (permalink / raw)
To: bzhao, linux-wireless, trivial, linux-kernel, netdev; +Cc: Masanari Iida
Correct spelling typo in wireless/mwifiex driver.
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
---
drivers/net/wireless/mwifiex/sta_ioctl.c | 2 +-
drivers/net/wireless/mwifiex/usb.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 552d72e..21035e6 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -463,7 +463,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
}
if (adapter->hs_activated) {
- dev_dbg(adapter->dev, "cmd: HS Already actived\n");
+ dev_dbg(adapter->dev, "cmd: HS Already activated\n");
return true;
}
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 22a5916..5eb3b33 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -351,7 +351,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
card->udev = udev;
card->intf = intf;
- pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocl=%#x\n",
+ pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
udev->descriptor.bDeviceSubClass,
udev->descriptor.bDeviceProtocol);
--
1.8.0.1.347.gf94c325
^ permalink raw reply related
* [PATCH] smsc: RFC: Workaround for problems with lan8710 phy auto MDI-X
From: Peter Turczak @ 2012-11-30 13:11 UTC (permalink / raw)
To: David Miller, Otavio Salvador, Javier Martinez Canillas,
Jiri Kosina, Christian Hohnstaedt, netdev, linux-kernel
Hi all,
while debugging network outages on a customers hardware I found, that the MDI-X function of the lan8710 phy seemed to cause trouble.
When connecting to almost any kind of 100/1000MBit switch, the link would seem to come up and data where sent out to the network. But all incoming packets got lost somehow. This is quite bad, as the system runs from nfsroot while booting up during development.
When I disabled the auto MDI-X function of the phy the problem went away.
Signed-off-by: Peter Turczak <pt@netconsequence.de>
---
drivers/net/phy/Kconfig | 10 ++++++++++
drivers/net/phy/smsc.c | 15 +++++++++++++++
include/linux/smscphy.h | 5 +++++
3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 961f0b2..341f5aa 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -60,6 +60,16 @@ config SMSC_PHY
---help---
Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
+config SMSC_PHY_DISABLE_AUTOX
+ bool "Disable MDI-X upon start"
+ depends on SMSC_PHY
+ ---help---
+ When you experience problems estabishing a stable connection
+ to a network and you have e.g. a LAN8710 ethernet phy
+ this option might help you out.
+
+ In doubt, say N
+
config BROADCOM_PHY
tristate "Drivers for Broadcom PHYs"
---help---
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 88e3991..651f71e 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -24,6 +24,8 @@
#include <linux/netdevice.h>
#include <linux/smscphy.h>
+static struct phy_driver lan8710_driver;
+
static int smsc_phy_config_intr(struct phy_device *phydev)
{
int rc = phy_write (phydev, MII_LAN83C185_IM,
@@ -53,6 +55,19 @@ static int smsc_phy_config_init(struct phy_device *phydev)
if (rc < 0)
return rc;
+#ifdef CONFIG_SMSC_PHY_DISABLE_AUTOX
+ if (phydev->drv == &lan8710_driver) {
+ rc = phy_read(phydev, MII_LAN8710_SCSI);
+ if (rc < 0)
+ return rc;
+ rc = phy_write(phydev, MII_LAN8710_SCSI,
+ rc | MII_LAN8710_SCSI_AMDIXCTRL);
+
+ if (rc < 0)
+ return rc;
+ }
+#endif
+
return smsc_phy_ack_interrupt (phydev);
}
diff --git a/include/linux/smscphy.h b/include/linux/smscphy.h
index ce718cb..4084b64 100644
--- a/include/linux/smscphy.h
+++ b/include/linux/smscphy.h
@@ -22,4 +22,9 @@
#define MII_LAN83C185_EDPWRDOWN (1 << 13) /* EDPWRDOWN */
#define MII_LAN83C185_ENERGYON (1 << 1) /* ENERGYON */
+#define MII_LAN8710_SCSI 27 /* Special Control/Status register */
+
+#define MII_LAN8710_SCSI_AMDIXCTRL (1<<15) /* Flag to disable Auto-MDIX */
+
+
#endif /* __LINUX_SMSCPHY_H__ */
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] sctp: fix CONFIG_SCTP_DBG_MSG=y null pointer dereference in sctp_v6_get_dst()
From: Vlad Yasevich @ 2012-11-30 14:18 UTC (permalink / raw)
To: Tommi Rantala
Cc: linux-sctp, netdev, Neil Horman, Sridhar Samudrala,
David S. Miller, Dave Jones
In-Reply-To: <1354267062-15888-1-git-send-email-tt.rantala@gmail.com>
On 11/30/2012 04:17 AM, Tommi Rantala wrote:
> Trinity (the syscall fuzzer) triggered the following BUG, reproducible
> only when the kernel is configured with CONFIG_SCTP_DBG_MSG=y.
>
> When CONFIG_SCTP_DBG_MSG is not set, the null pointer is never
> dereferenced.
>
> ---[ end trace a4de0bfcb38a3642 ]---
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000100
> IP: [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> PGD 4eead067 PUD 4e472067 PMD 0
> Oops: 0000 [#1] PREEMPT SMP
> Modules linked in:
> CPU 3
> Pid: 21324, comm: trinity-child11 Tainted: G W 3.7.0-rc7+ #61 ASUSTeK Computer INC. EB1012/EB1012
> RIP: 0010:[<ffffffff8136796e>] [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> RSP: 0018:ffff88004e4637a0 EFLAGS: 00010046
> RAX: ffff88004e4637da RBX: ffff88004e4637da RCX: 0000000000000000
> RDX: ffffffff8246e92a RSI: 0000000000000100 RDI: ffff88004e4637da
> RBP: ffff88004e4637a8 R08: 000000000000ffff R09: 000000000000ffff
> R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8289d600
> R13: ffffffff8289d230 R14: ffffffff8246e928 R15: ffffffff8289d600
> FS: 00007fed95153700(0000) GS:ffff88005fd80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000100 CR3: 000000004eeac000 CR4: 00000000000007e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process trinity-child11 (pid: 21324, threadinfo ffff88004e462000, task ffff8800524b0000)
> Stack:
> ffff88004e4637da ffff88004e463828 ffffffff81368eee 000000004e4637d8
> ffffffff0000ffff ffff88000000ffff 0000000000000000 000000004e4637f8
> ffffffff826285d8 ffff88004e4637f8 0000000000000000 ffff8800524b06b0
> Call Trace:
> [<ffffffff81368eee>] ip6_addr_string.isra.11+0x3e/0xa0
> [<ffffffff81369183>] pointer.isra.12+0x233/0x2d0
> [<ffffffff810a413a>] ? vprintk_emit+0x1ba/0x450
> [<ffffffff8110953d>] ? trace_hardirqs_on_caller+0x10d/0x1a0
> [<ffffffff81369757>] vsnprintf+0x187/0x5d0
> [<ffffffff81369c62>] vscnprintf+0x12/0x30
> [<ffffffff810a4028>] vprintk_emit+0xa8/0x450
> [<ffffffff81e5cb00>] printk+0x49/0x4b
> [<ffffffff81d17221>] sctp_v6_get_dst+0x731/0x780
> [<ffffffff81d16e15>] ? sctp_v6_get_dst+0x325/0x780
> [<ffffffff81d00a96>] sctp_transport_route+0x46/0x120
> [<ffffffff81cff0f1>] sctp_assoc_add_peer+0x161/0x350
> [<ffffffff81d0fd8d>] sctp_sendmsg+0x6cd/0xcb0
> [<ffffffff81b55bf0>] ? inet_create+0x670/0x670
> [<ffffffff81b55cfb>] inet_sendmsg+0x10b/0x220
> [<ffffffff81b55bf0>] ? inet_create+0x670/0x670
> [<ffffffff81a72a64>] ? sock_update_classid+0xa4/0x2b0
> [<ffffffff81a72ab0>] ? sock_update_classid+0xf0/0x2b0
> [<ffffffff81a6ac1c>] sock_sendmsg+0xdc/0xf0
> [<ffffffff8118e9e5>] ? might_fault+0x85/0x90
> [<ffffffff8118e99c>] ? might_fault+0x3c/0x90
> [<ffffffff81a6e12a>] sys_sendto+0xfa/0x130
> [<ffffffff810a9887>] ? do_setitimer+0x197/0x380
> [<ffffffff81e960d5>] ? sysret_check+0x22/0x5d
> [<ffffffff81e960a9>] system_call_fastpath+0x16/0x1b
> Code: 01 eb 89 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 f8 31 c9 48 89 e5 53 eb 12 0f 1f 40 00 48 83 c1 01 48 83 c0 04 48 83 f9 08 74 70 <0f> b6 3c 4e 89 fb 83 e7 0f c0 eb 04 41 89 d8 41 83 e0 0f 0f b6
> RIP [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> RSP <ffff88004e4637a0>
> CR2: 0000000000000100
> ---[ end trace a4de0bfcb38a3643 ]---
>
> Signed-off-by: Tommi Rantala <tt.rantala@gmail.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Thanks
-vlad
> ---
> net/sctp/ipv6.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index ea14cb4..f3f0f4d 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -345,7 +345,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
> }
>
> out:
> - if (!IS_ERR(dst)) {
> + if (!IS_ERR_OR_NULL(dst)) {
> struct rt6_info *rt;
> rt = (struct rt6_info *)dst;
> t->dst = dst;
>
^ permalink raw reply
* Re: [PATCH iproute2 v1] Add mdb command to bridge
From: Cong Wang @ 2012-11-30 14:50 UTC (permalink / raw)
To: Thomas Graf
Cc: netdev, bridge, Herbert Xu, Stephen Hemminger, David S. Miller,
Jesper Dangaard Brouer
In-Reply-To: <20121130105449.GE30697@casper.infradead.org>
On Fri, 2012-11-30 at 10:54 +0000, Thomas Graf wrote:
>
> You shouldn't need to duplicate the attribute ids and struct br_port_msg
> in iproute2. Just put these definitions in a uapi kernel header and
> include the header from iproute2.
Right, I was confused by include/linux/rtnetlink.h, thought iproute2 has
its own copy of these headers, but they should be exported from kernel.
Thanks!
^ permalink raw reply
* Re: [PATCH net-next v1 1/2] bridge: export port_no and port_id via IFA_INFO_DATA
From: Cong Wang @ 2012-11-30 14:51 UTC (permalink / raw)
To: Thomas Graf
Cc: netdev, bridge, Herbert Xu, Jesper Dangaard Brouer,
Stephen Hemminger, David S. Miller
In-Reply-To: <20121130101814.GD30697@casper.infradead.org>
On Fri, 2012-11-30 at 10:18 +0000, Thomas Graf wrote:
> On 11/30/12 at 05:58pm, Cong Wang wrote:
> > @@ -168,6 +172,8 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
> > [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
> > [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
> > [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
> > + [IFLA_BRPORT_NO] = { .type = NLA_U16 },
> > + [IFLA_BRPORT_ID] = { .type = NLA_U16 },
> > };
> >
> > /* Change the state of the port and notify spanning tree */
>
> I missed this in the first round. Not much of a point in adding policy
> entries if the attributes are read-only as in this case.
Yeah, remove these lines now.
^ permalink raw reply
* Re: [net-next PATCH V2 1/9] net: frag evictor, avoid killing warm frag queues
From: Eric Dumazet @ 2012-11-30 14:52 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: David Miller, fw, netdev, pablo, tgraf, amwang, kaber, paulmck,
herbert
In-Reply-To: <1354269846.11754.381.camel@localhost>
On Fri, 2012-11-30 at 11:04 +0100, Jesper Dangaard Brouer wrote:
> So, let me instead show, with tests, that the evictor strategy is
> broken, while keeping the original default thresh settings:
>
> # grep . /proc/sys/net/ipv4/ipfrag_*_thresh
> /proc/sys/net/ipv4/ipfrag_high_thresh:262144
> /proc/sys/net/ipv4/ipfrag_low_thresh:196608
>
> Test purpose, I will on a single 10G link demonstrate, that starting
> several "N" netperf UDP fragmentation flows, will hurt performance, and
> then claim this is caused by the bad evictor strategy.
>
> Test setup:
> - Disable Ethernet flow control
> - netperf packet size 65507
> - Run netserver on one NUMA node
> - Start netperf clients against a NIC on the other NUMA node
> - (The NUMA imbalance helps the effect occur at lower N)
>
> Result: N=1 8040 Mbit/s
> Result: N=2 9584 Mbit/s (4739+4845)
> Result: N=3 4055 Mbit/s (1436+1371+1248)
> Result: N=4 2247 Mbit/s (1538+29+54+626)
> Result: N=5 879 Mbit/s (78+152+226+125+298)
> Result: N=6 293 Mbit/s (85+55+32+57+46+18)
> Result: N=7 354 Mbit/s (70+47+33+80+20+72+32)
>
> Can we, now, agree that the current evictor strategy is broken?!?
Your setup is broken for sure. I dont know how you expect that many
datagrams being correctly reassembled with ipfrag_high_thresh=262144
No matter strategy is implemented, an attacker knows it and can send
frags so that regular workload is denied. Kernel cant decide which
packets are more likely to be completed.
BTW, install fq_codel at the sender side, so that frags are nicely
interleaved. Because on real networks, frags of an UDP datagram rarely
come to destination in a single train with no alien packets inside the
train.
You focus on a particular lab setup and particular workload, you
should consider that if an application _really_ depends on frags, then
the receiver is likely to be a target for various frag attacks.
^ permalink raw reply
* [PATCH 0/2] smsc75xx enhancements
From: Steve Glendinning @ 2012-11-30 14:52 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
This patchset, as requestes, expands the macros used in
smsc75xx to make the flow control clearer.
I've left the fix in a separate patch, so the macro-
expanding patch should have zero functional change.
Steve Glendinning (2):
smsc75xx: don't call usbnet_resume if usbnet_suspend fails
smsc75xx: expand check_ macros
drivers/net/usb/smsc75xx.c | 735 ++++++++++++++++++++++++++++++++++----------
1 file changed, 576 insertions(+), 159 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH 1/2] smsc75xx: don't call usbnet_resume if usbnet_suspend fails
From: Steve Glendinning @ 2012-11-30 14:52 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
In-Reply-To: <1354287164-9884-1-git-send-email-steve.glendinning@shawell.net>
If usbnet_suspend returns an error we don't want to call
usbnet_resume to clean up, but instead just return the error.
If usbnet_suspend *does* succeed, and we have a problem further
on, the desired behaviour is still to call usbnet_resume
to clean up before returning.
Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
---
drivers/net/usb/smsc75xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 1823806..86d9249 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -1411,7 +1411,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
int ret;
ret = usbnet_suspend(intf, message);
- check_warn_goto_done(ret, "usbnet_suspend error\n");
+ check_warn_return(ret, "usbnet_suspend error\n");
if (pdata->suspend_flags) {
netdev_warn(dev->net, "error during last resume\n");
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/2] smsc75xx: expand check_ macros
From: Steve Glendinning @ 2012-11-30 14:52 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
In-Reply-To: <1354287164-9884-1-git-send-email-steve.glendinning@shawell.net>
These macros, while reducing the amount of code, hide flow control
and make the code more confusing to follow and review. This patch
expands them. It should have no functional effect on the driver.
Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
---
drivers/net/usb/smsc75xx.c | 735 ++++++++++++++++++++++++++++++++++----------
1 file changed, 576 insertions(+), 159 deletions(-)
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 86d9249..1cbd936 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -64,15 +64,6 @@
#define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \
SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3)
-#define check_warn(ret, fmt, args...) \
- ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
-
-#define check_warn_return(ret, fmt, args...) \
- ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
-
-#define check_warn_goto_done(ret, fmt, args...) \
- ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
-
struct smsc75xx_priv {
struct usbnet *dev;
u32 rfe_ctl;
@@ -182,7 +173,10 @@ static __must_check int __smsc75xx_phy_wait_not_busy(struct usbnet *dev,
do {
ret = __smsc75xx_read_reg(dev, MII_ACCESS, &val, in_pm);
- check_warn_return(ret, "Error reading MII_ACCESS\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading MII_ACCESS\n");
+ return ret;
+ }
if (!(val & MII_ACCESS_BUSY))
return 0;
@@ -202,7 +196,10 @@ static int __smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx,
/* confirm MII not busy */
ret = __smsc75xx_phy_wait_not_busy(dev, in_pm);
- check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "MII is busy in smsc75xx_mdio_read\n");
+ goto done;
+ }
/* set the address, index & direction (read from PHY) */
phy_id &= dev->mii.phy_id_mask;
@@ -211,13 +208,22 @@ static int __smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx,
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
| MII_ACCESS_READ | MII_ACCESS_BUSY;
ret = __smsc75xx_write_reg(dev, MII_ACCESS, addr, in_pm);
- check_warn_goto_done(ret, "Error writing MII_ACCESS\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing MII_ACCESS\n");
+ goto done;
+ }
ret = __smsc75xx_phy_wait_not_busy(dev, in_pm);
- check_warn_goto_done(ret, "Timed out reading MII reg %02X\n", idx);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx);
+ goto done;
+ }
ret = __smsc75xx_read_reg(dev, MII_DATA, &val, in_pm);
- check_warn_goto_done(ret, "Error reading MII_DATA\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading MII_DATA\n");
+ goto done;
+ }
ret = (u16)(val & 0xFFFF);
@@ -237,11 +243,17 @@ static void __smsc75xx_mdio_write(struct net_device *netdev, int phy_id,
/* confirm MII not busy */
ret = __smsc75xx_phy_wait_not_busy(dev, in_pm);
- check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "MII is busy in smsc75xx_mdio_write\n");
+ goto done;
+ }
val = regval;
ret = __smsc75xx_write_reg(dev, MII_DATA, val, in_pm);
- check_warn_goto_done(ret, "Error writing MII_DATA\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing MII_DATA\n");
+ goto done;
+ }
/* set the address, index & direction (write to PHY) */
phy_id &= dev->mii.phy_id_mask;
@@ -250,10 +262,16 @@ static void __smsc75xx_mdio_write(struct net_device *netdev, int phy_id,
| ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
| MII_ACCESS_WRITE | MII_ACCESS_BUSY;
ret = __smsc75xx_write_reg(dev, MII_ACCESS, addr, in_pm);
- check_warn_goto_done(ret, "Error writing MII_ACCESS\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing MII_ACCESS\n");
+ goto done;
+ }
ret = __smsc75xx_phy_wait_not_busy(dev, in_pm);
- check_warn_goto_done(ret, "Timed out writing MII reg %02X\n", idx);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx);
+ goto done;
+ }
done:
mutex_unlock(&dev->phy_mutex);
@@ -290,7 +308,10 @@ static int smsc75xx_wait_eeprom(struct usbnet *dev)
do {
ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
- check_warn_return(ret, "Error reading E2P_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading E2P_CMD\n");
+ return ret;
+ }
if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
break;
@@ -313,7 +334,10 @@ static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
do {
ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
- check_warn_return(ret, "Error reading E2P_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading E2P_CMD\n");
+ return ret;
+ }
if (!(val & E2P_CMD_BUSY))
return 0;
@@ -341,14 +365,20 @@ static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
for (i = 0; i < length; i++) {
val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing E2P_CMD\n");
+ return ret;
+ }
ret = smsc75xx_wait_eeprom(dev);
if (ret < 0)
return ret;
ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
- check_warn_return(ret, "Error reading E2P_DATA\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading E2P_DATA\n");
+ return ret;
+ }
data[i] = val & 0xFF;
offset++;
@@ -373,7 +403,10 @@ static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
/* Issue write/erase enable command */
val = E2P_CMD_BUSY | E2P_CMD_EWEN;
ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing E2P_CMD\n");
+ return ret;
+ }
ret = smsc75xx_wait_eeprom(dev);
if (ret < 0)
@@ -384,12 +417,18 @@ static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
/* Fill data register */
val = data[i];
ret = smsc75xx_write_reg(dev, E2P_DATA, val);
- check_warn_return(ret, "Error writing E2P_DATA\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing E2P_DATA\n");
+ return ret;
+ }
/* Send "write" command */
val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
ret = smsc75xx_write_reg(dev, E2P_CMD, val);
- check_warn_return(ret, "Error writing E2P_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing E2P_CMD\n");
+ return ret;
+ }
ret = smsc75xx_wait_eeprom(dev);
if (ret < 0)
@@ -408,7 +447,10 @@ static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
for (i = 0; i < 100; i++) {
u32 dp_sel;
ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
- check_warn_return(ret, "Error reading DP_SEL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading DP_SEL\n");
+ return ret;
+ }
if (dp_sel & DP_SEL_DPRDY)
return 0;
@@ -431,28 +473,49 @@ static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
mutex_lock(&pdata->dataport_mutex);
ret = smsc75xx_dataport_wait_not_busy(dev);
- check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "smsc75xx_dataport_write busy on entry\n");
+ goto done;
+ }
ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
- check_warn_goto_done(ret, "Error reading DP_SEL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading DP_SEL\n");
+ goto done;
+ }
dp_sel &= ~DP_SEL_RSEL;
dp_sel |= ram_select;
ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
- check_warn_goto_done(ret, "Error writing DP_SEL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing DP_SEL\n");
+ goto done;
+ }
for (i = 0; i < length; i++) {
ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
- check_warn_goto_done(ret, "Error writing DP_ADDR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing DP_ADDR\n");
+ goto done;
+ }
ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
- check_warn_goto_done(ret, "Error writing DP_DATA\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing DP_DATA\n");
+ goto done;
+ }
ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
- check_warn_goto_done(ret, "Error writing DP_CMD\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing DP_CMD\n");
+ goto done;
+ }
ret = smsc75xx_dataport_wait_not_busy(dev);
- check_warn_goto_done(ret, "smsc75xx_dataport_write timeout\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "smsc75xx_dataport_write timeout\n");
+ goto done;
+ }
}
done:
@@ -480,7 +543,8 @@ static void smsc75xx_deferred_multicast_write(struct work_struct *param)
DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn(ret, "Error writing RFE_CRL\n");
+ if (ret < 0)
+ netdev_warn(dev->net, "Error writing RFE_CRL\n");
}
static void smsc75xx_set_multicast(struct net_device *netdev)
@@ -554,10 +618,16 @@ static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
}
ret = smsc75xx_write_reg(dev, FLOW, flow);
- check_warn_return(ret, "Error writing FLOW\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing FLOW\n");
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
- check_warn_return(ret, "Error writing FCT_FLOW\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing FCT_FLOW\n");
+ return ret;
+ }
return 0;
}
@@ -574,7 +644,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)
PHY_INT_SRC_CLEAR_ALL);
ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
- check_warn_return(ret, "Error writing INT_STS\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing INT_STS\n");
+ return ret;
+ }
mii_check_media(mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
@@ -658,9 +731,10 @@ static int smsc75xx_ethtool_set_wol(struct net_device *net,
pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
ret = device_set_wakeup_enable(&dev->udev->dev, pdata->wolopts);
- check_warn_return(ret, "device_set_wakeup_enable error %d\n", ret);
+ if (ret < 0)
+ netdev_warn(dev->net, "device_set_wakeup_enable error %d\n", ret);
- return 0;
+ return ret;
}
static const struct ethtool_ops smsc75xx_ethtool_ops = {
@@ -713,19 +787,29 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)
u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
- check_warn_return(ret, "Failed to write RX_ADDRH: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write RX_ADDRH: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
- check_warn_return(ret, "Failed to write RX_ADDRL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write RX_ADDRL: %d\n", ret);
+ return ret;
+ }
addr_hi |= ADDR_FILTX_FB_VALID;
ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
- check_warn_return(ret, "Failed to write ADDR_FILTX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write ADDR_FILTX: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
- check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d\n", ret);
+ if (ret < 0)
+ netdev_warn(dev->net, "Failed to write ADDR_FILTX+4: %d\n", ret);
- return 0;
+ return ret;
}
static int smsc75xx_phy_initialize(struct usbnet *dev)
@@ -747,7 +831,10 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
do {
msleep(10);
bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
- check_warn_return(bmcr, "Error reading MII_BMCR\n");
+ if (bmcr < 0) {
+ netdev_warn(dev->net, "Error reading MII_BMCR\n");
+ return bmcr;
+ }
timeout++;
} while ((bmcr & BMCR_RESET) && (timeout < 100));
@@ -764,7 +851,11 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
/* read and write to clear phy interrupt status */
ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
- check_warn_return(ret, "Error reading PHY_INT_SRC\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PHY_INT_SRC\n");
+ return ret;
+ }
+
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
@@ -782,14 +873,20 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
bool rxenabled;
ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
- check_warn_return(ret, "Failed to read MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret);
+ return ret;
+ }
rxenabled = ((buf & MAC_RX_RXEN) != 0);
if (rxenabled) {
buf &= ~MAC_RX_RXEN;
ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret);
+ return ret;
+ }
}
/* add 4 to size for FCS */
@@ -797,12 +894,18 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret);
+ return ret;
+ }
if (rxenabled) {
buf |= MAC_RX_RXEN;
ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret);
+ return ret;
+ }
}
return 0;
@@ -813,7 +916,10 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
struct usbnet *dev = netdev_priv(netdev);
int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
- check_warn_return(ret, "Failed to set mac rx frame length\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to set mac rx frame length\n");
+ return ret;
+ }
return usbnet_change_mtu(netdev, new_mtu);
}
@@ -838,9 +944,10 @@ static int smsc75xx_set_features(struct net_device *netdev,
/* it's racing here! */
ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn_return(ret, "Error writing RFE_CTL\n");
+ if (ret < 0)
+ netdev_warn(dev->net, "Error writing RFE_CTL\n");
- return 0;
+ return ret;
}
static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm)
@@ -853,7 +960,10 @@ static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm)
ret = __smsc75xx_read_reg(dev, PMT_CTL, &buf, in_pm);
- check_warn_return(ret, "Failed to read PMT_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret);
+ return ret;
+ }
if (buf & PMT_CTL_DEV_RDY)
return 0;
@@ -875,21 +985,33 @@ static int smsc75xx_reset(struct usbnet *dev)
netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset\n");
ret = smsc75xx_wait_ready(dev, 0);
- check_warn_return(ret, "device not ready in smsc75xx_reset\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "device not ready in smsc75xx_reset\n");
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
buf |= HW_CFG_LRST;
ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret);
+ return ret;
+ }
timeout = 0;
do {
msleep(10);
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
timeout++;
} while ((buf & HW_CFG_LRST) && (timeout < 100));
@@ -901,18 +1023,27 @@ static int smsc75xx_reset(struct usbnet *dev)
netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY\n");
ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
- check_warn_return(ret, "Failed to read PMT_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret);
+ return ret;
+ }
buf |= PMT_CTL_PHY_RST;
ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
- check_warn_return(ret, "Failed to write PMT_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write PMT_CTL: %d\n", ret);
+ return ret;
+ }
timeout = 0;
do {
msleep(10);
ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
- check_warn_return(ret, "Failed to read PMT_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret);
+ return ret;
+ }
timeout++;
} while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
@@ -926,13 +1057,19 @@ static int smsc75xx_reset(struct usbnet *dev)
smsc75xx_init_mac_address(dev);
ret = smsc75xx_set_mac_address(dev);
- check_warn_return(ret, "Failed to set mac address\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to set mac address\n");
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "MAC Address: %pM\n",
dev->net->dev_addr);
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x\n",
buf);
@@ -940,10 +1077,16 @@ static int smsc75xx_reset(struct usbnet *dev)
buf |= HW_CFG_BIR;
ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after writing HW_CFG_BIR: 0x%08x\n",
buf);
@@ -963,36 +1106,57 @@ static int smsc75xx_reset(struct usbnet *dev)
(ulong)dev->rx_urb_size);
ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
- check_warn_return(ret, "Failed to write BURST_CAP: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
- check_warn_return(ret, "Failed to read BURST_CAP: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net,
"Read Value from BURST_CAP after writing: 0x%08x\n", buf);
ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
- check_warn_return(ret, "Failed to write BULK_IN_DLY: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write BULK_IN_DLY: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
- check_warn_return(ret, "Failed to read BULK_IN_DLY: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net,
"Read Value from BULK_IN_DLY after writing: 0x%08x\n", buf);
if (turbo_mode) {
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x\n", buf);
buf |= (HW_CFG_MEF | HW_CFG_BCE);
ret = smsc75xx_write_reg(dev, HW_CFG, buf);
- check_warn_return(ret, "Failed to write HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
- check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x\n", buf);
}
@@ -1000,58 +1164,92 @@ static int smsc75xx_reset(struct usbnet *dev)
/* set FIFO sizes */
buf = (MAX_RX_FIFO_SIZE - 512) / 512;
ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
- check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FCT_RX_FIFO_END: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x\n", buf);
buf = (MAX_TX_FIFO_SIZE - 512) / 512;
ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
- check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FCT_TX_FIFO_END: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x\n", buf);
ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
- check_warn_return(ret, "Failed to write INT_STS: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write INT_STS: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, ID_REV, &buf);
- check_warn_return(ret, "Failed to read ID_REV: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", buf);
ret = smsc75xx_read_reg(dev, E2P_CMD, &buf);
- check_warn_return(ret, "Failed to read E2P_CMD: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read E2P_CMD: %d\n", ret);
+ return ret;
+ }
/* only set default GPIO/LED settings if no EEPROM is detected */
if (!(buf & E2P_CMD_LOADED)) {
ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
- check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d\n",
- ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read LED_GPIO_CFG: %d\n", ret);
+ return ret;
+ }
buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
- check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d\n",
- ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write LED_GPIO_CFG: %d\n", ret);
+ return ret;
+ }
}
ret = smsc75xx_write_reg(dev, FLOW, 0);
- check_warn_return(ret, "Failed to write FLOW: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
- check_warn_return(ret, "Failed to write FCT_FLOW: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FCT_FLOW: %d\n", ret);
+ return ret;
+ }
/* Don't need rfe_ctl_lock during initialisation */
ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
- check_warn_return(ret, "Failed to read RFE_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read RFE_CTL: %d\n", ret);
+ return ret;
+ }
pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
- check_warn_return(ret, "Failed to write RFE_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write RFE_CTL: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
- check_warn_return(ret, "Failed to read RFE_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read RFE_CTL: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x\n",
pdata->rfe_ctl);
@@ -1062,65 +1260,107 @@ static int smsc75xx_reset(struct usbnet *dev)
smsc75xx_set_multicast(dev->net);
ret = smsc75xx_phy_initialize(dev);
- check_warn_return(ret, "Failed to initialize PHY: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to initialize PHY: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
- check_warn_return(ret, "Failed to read INT_EP_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret);
+ return ret;
+ }
/* enable PHY interrupts */
buf |= INT_ENP_PHY_INT;
ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
- check_warn_return(ret, "Failed to write INT_EP_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret);
+ return ret;
+ }
/* allow mac to detect speed and duplex from phy */
ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
- check_warn_return(ret, "Failed to read MAC_CR: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret);
+ return ret;
+ }
buf |= (MAC_CR_ADD | MAC_CR_ASD);
ret = smsc75xx_write_reg(dev, MAC_CR, buf);
- check_warn_return(ret, "Failed to write MAC_CR: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_CR: %d\n", ret);
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
- check_warn_return(ret, "Failed to read MAC_TX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read MAC_TX: %d\n", ret);
+ return ret;
+ }
buf |= MAC_TX_TXEN;
ret = smsc75xx_write_reg(dev, MAC_TX, buf);
- check_warn_return(ret, "Failed to write MAC_TX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_TX: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x\n", buf);
ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
- check_warn_return(ret, "Failed to read FCT_TX_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read FCT_TX_CTL: %d\n", ret);
+ return ret;
+ }
buf |= FCT_TX_CTL_EN;
ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
- check_warn_return(ret, "Failed to write FCT_TX_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FCT_TX_CTL: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf);
ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
- check_warn_return(ret, "Failed to set max rx frame length\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to set max rx frame length\n");
+ return ret;
+ }
ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
- check_warn_return(ret, "Failed to read MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret);
+ return ret;
+ }
buf |= MAC_RX_RXEN;
ret = smsc75xx_write_reg(dev, MAC_RX, buf);
- check_warn_return(ret, "Failed to write MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x\n", buf);
ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
- check_warn_return(ret, "Failed to read FCT_RX_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read FCT_RX_CTL: %d\n", ret);
+ return ret;
+ }
buf |= FCT_RX_CTL_EN;
ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
- check_warn_return(ret, "Failed to write FCT_RX_CTL: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FCT_RX_CTL: %d\n", ret);
+ return ret;
+ }
netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x\n", buf);
@@ -1149,7 +1389,10 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
ret = usbnet_get_endpoints(dev, intf);
- check_warn_return(ret, "usbnet_get_endpoints failed: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
+ return ret;
+ }
dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
GFP_KERNEL);
@@ -1181,7 +1424,10 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
/* Init all registers */
ret = smsc75xx_reset(dev);
- check_warn_return(ret, "smsc75xx_reset error %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret);
+ return ret;
+ }
dev->net->netdev_ops = &smsc75xx_netdev_ops;
dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
@@ -1215,19 +1461,34 @@ static int smsc75xx_write_wuff(struct usbnet *dev, int filter, u32 wuf_cfg,
int ret;
ret = smsc75xx_write_reg(dev, cfg_base, wuf_cfg);
- check_warn_return(ret, "Error writing WUF_CFGX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_CFGX\n");
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, mask_base, wuf_mask1);
- check_warn_return(ret, "Error writing WUF_MASKX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_MASKX\n");
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, mask_base + 4, 0);
- check_warn_return(ret, "Error writing WUF_MASKX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_MASKX\n");
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, mask_base + 8, 0);
- check_warn_return(ret, "Error writing WUF_MASKX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_MASKX\n");
+ return ret;
+ }
ret = smsc75xx_write_reg(dev, mask_base + 12, 0);
- check_warn_return(ret, "Error writing WUF_MASKX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_MASKX\n");
+ return ret;
+ }
return 0;
}
@@ -1239,13 +1500,19 @@ static int smsc75xx_enter_suspend0(struct usbnet *dev)
int ret;
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val &= (~(PMT_CTL_SUS_MODE | PMT_CTL_PHY_RST));
val |= PMT_CTL_SUS_MODE_0 | PMT_CTL_WOL_EN | PMT_CTL_WUPS;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
pdata->suspend_flags |= SUSPEND_SUSPEND0;
@@ -1259,20 +1526,29 @@ static int smsc75xx_enter_suspend1(struct usbnet *dev)
int ret;
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST);
val |= PMT_CTL_SUS_MODE_1;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
/* clear wol status, enable energy detection */
val &= ~PMT_CTL_WUPS;
val |= (PMT_CTL_WUPS_ED | PMT_CTL_ED_EN);
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
pdata->suspend_flags |= SUSPEND_SUSPEND1;
@@ -1286,13 +1562,19 @@ static int smsc75xx_enter_suspend2(struct usbnet *dev)
int ret;
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST);
val |= PMT_CTL_SUS_MODE_2;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
pdata->suspend_flags |= SUSPEND_SUSPEND2;
@@ -1306,7 +1588,10 @@ static int smsc75xx_enter_suspend3(struct usbnet *dev)
int ret;
ret = smsc75xx_read_reg_nopm(dev, FCT_RX_CTL, &val);
- check_warn_return(ret, "Error reading FCT_RX_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading FCT_RX_CTL\n");
+ return ret;
+ }
if (val & FCT_RX_CTL_RXUSED) {
netdev_dbg(dev->net, "rx fifo not empty in autosuspend\n");
@@ -1314,20 +1599,29 @@ static int smsc75xx_enter_suspend3(struct usbnet *dev)
}
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST);
val |= PMT_CTL_SUS_MODE_3 | PMT_CTL_RES_CLR_WKP_EN;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
/* clear wol status */
val &= ~PMT_CTL_WUPS;
val |= PMT_CTL_WUPS_WOL;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
pdata->suspend_flags |= SUSPEND_SUSPEND3;
@@ -1343,11 +1637,17 @@ static int smsc75xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask)
/* read to clear */
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_SRC);
- check_warn_return(ret, "Error reading PHY_INT_SRC\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PHY_INT_SRC\n");
+ return ret;
+ }
/* enable interrupt source */
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_MASK);
- check_warn_return(ret, "Error reading PHY_INT_MASK\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PHY_INT_MASK\n");
+ return ret;
+ }
ret |= mask;
@@ -1363,10 +1663,16 @@ static int smsc75xx_link_ok_nopm(struct usbnet *dev)
/* first, a dummy read, needed to latch some MII phys */
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR);
- check_warn_return(ret, "Error reading MII_BMSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading MII_BMSR\n");
+ return ret;
+ }
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR);
- check_warn_return(ret, "Error reading MII_BMSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading MII_BMSR\n");
+ return ret;
+ }
return !!(ret & BMSR_LSTATUS);
}
@@ -1388,7 +1694,10 @@ static int smsc75xx_autosuspend(struct usbnet *dev, u32 link_up)
/* enable PHY wakeup events for if cable is attached */
ret = smsc75xx_enable_phy_wakeup_interrupts(dev,
PHY_INT_MASK_ANEG_COMP);
- check_warn_return(ret, "error enabling PHY wakeup ints\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
+ return ret;
+ }
netdev_info(dev->net, "entering SUSPEND1 mode\n");
return smsc75xx_enter_suspend1(dev);
@@ -1397,7 +1706,10 @@ static int smsc75xx_autosuspend(struct usbnet *dev, u32 link_up)
/* enable PHY wakeup events so we remote wakeup if cable is pulled */
ret = smsc75xx_enable_phy_wakeup_interrupts(dev,
PHY_INT_MASK_LINK_DOWN);
- check_warn_return(ret, "error enabling PHY wakeup ints\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
+ return ret;
+ }
netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n");
return smsc75xx_enter_suspend3(dev);
@@ -1411,7 +1723,10 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
int ret;
ret = usbnet_suspend(intf, message);
- check_warn_return(ret, "usbnet_suspend error\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "usbnet_suspend error\n");
+ return ret;
+ }
if (pdata->suspend_flags) {
netdev_warn(dev->net, "error during last resume\n");
@@ -1436,20 +1751,32 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
/* disable energy detect (link up) & wake up events */
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val &= ~(WUCSR_MPEN | WUCSR_WUEN);
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_goto_done(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ goto done;
+ }
val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN);
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_goto_done(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ goto done;
+ }
ret = smsc75xx_enter_suspend2(dev);
goto done;
@@ -1458,7 +1785,10 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
if (pdata->wolopts & WAKE_PHY) {
ret = smsc75xx_enable_phy_wakeup_interrupts(dev,
(PHY_INT_MASK_ANEG_COMP | PHY_INT_MASK_LINK_DOWN));
- check_warn_goto_done(ret, "error enabling PHY wakeup ints\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
+ goto done;
+ }
/* if link is down then configure EDPD and enter SUSPEND1,
* otherwise enter SUSPEND0 below
@@ -1470,7 +1800,10 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
/* enable energy detect power-down mode */
ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id,
PHY_MODE_CTRL_STS);
- check_warn_goto_done(ret, "Error reading PHY_MODE_CTRL_STS\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PHY_MODE_CTRL_STS\n");
+ goto done;
+ }
ret |= MODE_CTRL_STS_EDPWRDOWN;
@@ -1489,7 +1822,10 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
/* disable all filters */
for (i = 0; i < WUF_NUM; i++) {
ret = smsc75xx_write_reg_nopm(dev, WUF_CFGX + i * 4, 0);
- check_warn_goto_done(ret, "Error writing WUF_CFGX\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUF_CFGX\n");
+ goto done;
+ }
}
if (pdata->wolopts & WAKE_MCAST) {
@@ -1499,7 +1835,10 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
val = WUF_CFGX_EN | WUF_CFGX_ATYPE_MULTICAST
| smsc_crc(mcast, 3);
ret = smsc75xx_write_wuff(dev, filter++, val, 0x0007);
- check_warn_goto_done(ret, "Error writing wakeup filter\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing wakeup filter\n");
+ goto done;
+ }
}
if (pdata->wolopts & WAKE_ARP) {
@@ -1509,102 +1848,159 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
val = WUF_CFGX_EN | WUF_CFGX_ATYPE_ALL | (0x0C << 16)
| smsc_crc(arp, 2);
ret = smsc75xx_write_wuff(dev, filter++, val, 0x0003);
- check_warn_goto_done(ret, "Error writing wakeup filter\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing wakeup filter\n");
+ goto done;
+ }
}
/* clear any pending pattern match packet status */
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val |= WUCSR_WUFR;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
netdev_info(dev->net, "enabling packet match detection\n");
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val |= WUCSR_WUEN;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
} else {
netdev_info(dev->net, "disabling packet match detection\n");
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val &= ~WUCSR_WUEN;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
}
/* disable magic, bcast & unicast wakeup sources */
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val &= ~(WUCSR_MPEN | WUCSR_BCST_EN | WUCSR_PFDA_EN);
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
if (pdata->wolopts & WAKE_PHY) {
netdev_info(dev->net, "enabling PHY wakeup\n");
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_goto_done(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ goto done;
+ }
/* clear wol status, enable energy detection */
val &= ~PMT_CTL_WUPS;
val |= (PMT_CTL_WUPS_ED | PMT_CTL_ED_EN);
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_goto_done(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ goto done;
+ }
}
if (pdata->wolopts & WAKE_MAGIC) {
netdev_info(dev->net, "enabling magic packet wakeup\n");
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
/* clear any pending magic packet status */
val |= WUCSR_MPR | WUCSR_MPEN;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
}
if (pdata->wolopts & WAKE_BCAST) {
netdev_info(dev->net, "enabling broadcast detection\n");
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val |= WUCSR_BCAST_FR | WUCSR_BCST_EN;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
}
if (pdata->wolopts & WAKE_UCAST) {
netdev_info(dev->net, "enabling unicast detection\n");
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_goto_done(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ goto done;
+ }
val |= WUCSR_WUFR | WUCSR_PFDA_EN;
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_goto_done(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ goto done;
+ }
}
/* enable receiver to enable frame reception */
ret = smsc75xx_read_reg_nopm(dev, MAC_RX, &val);
- check_warn_goto_done(ret, "Failed to read MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret);
+ goto done;
+ }
val |= MAC_RX_RXEN;
ret = smsc75xx_write_reg_nopm(dev, MAC_RX, val);
- check_warn_goto_done(ret, "Failed to write MAC_RX: %d\n", ret);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret);
+ goto done;
+ }
/* some wol options are enabled, so enter SUSPEND0 */
netdev_info(dev->net, "entering SUSPEND0 mode\n");
@@ -1632,39 +2028,60 @@ static int smsc75xx_resume(struct usb_interface *intf)
if (suspend_flags & SUSPEND_ALLMODES) {
/* Disable wakeup sources */
ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val);
- check_warn_return(ret, "Error reading WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading WUCSR\n");
+ return ret;
+ }
val &= ~(WUCSR_WUEN | WUCSR_MPEN | WUCSR_PFDA_EN
| WUCSR_BCST_EN);
ret = smsc75xx_write_reg_nopm(dev, WUCSR, val);
- check_warn_return(ret, "Error writing WUCSR\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing WUCSR\n");
+ return ret;
+ }
/* clear wake-up status */
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val &= ~PMT_CTL_WOL_EN;
val |= PMT_CTL_WUPS;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
}
if (suspend_flags & SUSPEND_SUSPEND2) {
netdev_info(dev->net, "resuming from SUSPEND2\n");
ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val);
- check_warn_return(ret, "Error reading PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error reading PMT_CTL\n");
+ return ret;
+ }
val |= PMT_CTL_PHY_PWRUP;
ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val);
- check_warn_return(ret, "Error writing PMT_CTL\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "Error writing PMT_CTL\n");
+ return ret;
+ }
}
ret = smsc75xx_wait_ready(dev, 1);
- check_warn_return(ret, "device not ready in smsc75xx_resume\n");
+ if (ret < 0) {
+ netdev_warn(dev->net, "device not ready in smsc75xx_resume\n");
+ return ret;
+ }
return usbnet_resume(intf);
}
--
1.7.10.4
^ permalink raw reply related
* Re: [net-next PATCH V2 1/9] net: frag evictor, avoid killing warm frag queues
From: Eric Dumazet @ 2012-11-30 14:57 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: David Miller, fw, netdev, pablo, tgraf, amwang, kaber, paulmck,
herbert, David Laight
In-Reply-To: <1354276891.11754.424.camel@localhost>
On Fri, 2012-11-30 at 13:01 +0100, Jesper Dangaard Brouer wrote:
> As the existing entries in the frag queues, are still being allowed
> packets through (even when the memory limit is exceeded). In
> worst-case, as DaveM explained, this can be as much as 100KBytes per
> entry (for 64K fragments).
Some NIC uses a plain page to hold an ethernet frame.
Consider an UDP packet using 512 bytes frags, the resulting packet after
reassembly can use 128 pages. Thats 512 KB of memory on x86.
^ permalink raw reply
* Re: [PATCH net-next v1 2/2] bridge: export multicast database via netlink
From: Cong Wang @ 2012-11-30 15:00 UTC (permalink / raw)
To: Thomas Graf
Cc: netdev, bridge, Herbert Xu, Stephen Hemminger, David S. Miller,
Jesper Dangaard Brouer
In-Reply-To: <20121130112618.GF30697@casper.infradead.org>
On Fri, 2012-11-30 at 11:26 +0000, Thomas Graf wrote:
> On 11/30/12 at 05:58pm, Cong Wang wrote:
> > +
> > + nest = nla_nest_start(skb, MDBA_ROUTER);
> > + if (nest == NULL)
> > + return -EMSGSIZE;
> > +
> > + hlist_for_each_entry_rcu(p, n, &br->router_list, rlist) {
> > + if (p && nla_put_u16(skb, MDBA_BRPORT_NO, p->port_no))
> > + goto fail;
> > + }
>
> port_no 0 is reserved, right?
>
> We can reduce message size here and make it easier to extend by
> using p->port_no as the attribute id by doing something like this:
>
> hlist_for_each_entry_rcu(p, n, &br->router_list, rlist)
> if (nla_put_flag(skb, p->port_no))
> goto fail;
>
> This will result in an empty attribute body for now and if you ever
> need to include more data you can simply start putting attributes
> insde that empty body and old users will continue to function.
I don't understand this. nla_put_flag() is used to put a flag (only one
bit set) into a netlink message, so why should we use it to put
p->port_no here? And why port_no 0 matters here?
[...]
> > +
> > + cb->seq = mdb->seq;
>
> I'm not sure how this is supposed to worl. cb->seq may not change
> throughout the complete dump process or the dump will be interrupted
> and the user is required to restart.
>
> Each bridge will have its own mdb resulting in a differing seq.
>
So I should use net->dev_base_seq + mdb->seq ?
All of the rest suggestions are taken by me.
Thanks for your detailed review!
^ permalink raw reply
* Re: linux-next: Tree for Nov 29 (netlabel)
From: Paul Moore @ 2012-11-30 15:19 UTC (permalink / raw)
To: Randy Dunlap
Cc: Stephen Rothwell, linux-next, linux-kernel,
netdev@vger.kernel.org
In-Reply-To: <50B7F846.70202@infradead.org>
On Thursday, November 29, 2012 04:05:26 PM Randy Dunlap wrote:
> On 11/28/2012 10:40 PM, Stephen Rothwell wrote:
> > Hi all,
>
> > Changes since 20121128:
> (on i386:)
If I had to guess it looks like CONFIG_NETLABEL needs to be dependent on
CONFIG_INET. While the net/ Kconfig only pulls in the net/netlabel Kconfig if
CONFIG_INET is defined, I'm guessing that without the explicit dependency
there is nothing preventing someone from arriving at a bad configuration as we
see here.
Let me test this out to make sure my reasoning is right and if it is I'll post
a patch to netdev later today.
Thanks for catching this.
> net/built-in.o: In function `netlbl_cfg_cipsov4_add':
> (.text+0x61757): undefined reference to `cipso_v4_doi_add'
> net/built-in.o: In function `netlbl_cfg_cipsov4_del':
> (.text+0x6177d): undefined reference to `cipso_v4_doi_remove'
> net/built-in.o: In function `netlbl_cfg_cipsov4_map_add':
> (.text+0x617ae): undefined reference to `cipso_v4_doi_getdef'
> net/built-in.o: In function `netlbl_cfg_cipsov4_map_add':
> (.text+0x61a49): undefined reference to `cipso_v4_doi_putdef'
> net/built-in.o: In function `netlbl_sock_setattr':
> (.text+0x6218c): undefined reference to `cipso_v4_sock_setattr'
> net/built-in.o: In function `netlbl_sock_delattr':
> (.text+0x6220b): undefined reference to `cipso_v4_sock_delattr'
> net/built-in.o: In function `netlbl_sock_getattr':
> (.text+0x62238): undefined reference to `cipso_v4_sock_getattr'
> net/built-in.o: In function `netlbl_conn_setattr':
> (.text+0x622de): undefined reference to `cipso_v4_sock_setattr'
> net/built-in.o: In function `netlbl_conn_setattr':
> (.text+0x62303): undefined reference to `cipso_v4_sock_delattr'
> net/built-in.o: In function `netlbl_req_setattr':
> (.text+0x62429): undefined reference to `cipso_v4_req_setattr'
> net/built-in.o: In function `netlbl_req_setattr':
> (.text+0x6244e): undefined reference to `cipso_v4_req_delattr'
> net/built-in.o: In function `netlbl_req_delattr':
> (.text+0x624ba): undefined reference to `cipso_v4_req_delattr'
> net/built-in.o: In function `netlbl_skbuff_setattr':
> (.text+0x62551): undefined reference to `cipso_v4_skbuff_setattr'
> net/built-in.o: In function `netlbl_skbuff_setattr':
> (.text+0x62576): undefined reference to `cipso_v4_skbuff_delattr'
> net/built-in.o: In function `netlbl_skbuff_getattr':
> (.text+0x62619): undefined reference to `cipso_v4_skbuff_getattr'
> net/built-in.o: In function `netlbl_skbuff_err':
> (.text+0x62685): undefined reference to `cipso_v4_error'
> net/built-in.o: In function `netlbl_cache_invalidate':
> (.text+0x626ab): undefined reference to `cipso_v4_cache_invalidate'
> net/built-in.o: In function `netlbl_cache_add':
> (.text+0x626ec): undefined reference to `cipso_v4_cache_add'
> net/built-in.o: In function `netlbl_domhsh_remove_entry':
> (.text+0x63294): undefined reference to `cipso_v4_doi_putdef'
> net/built-in.o: In function `netlbl_domhsh_remove_entry':
> (.text+0x632eb): undefined reference to `cipso_v4_doi_putdef'
> net/built-in.o: In function `netlbl_domhsh_remove_af4':
> (.text+0x6349b): undefined reference to `cipso_v4_doi_putdef'
> net/built-in.o: In function `netlbl_mgmt_add_common.clone.1':
> netlabel_mgmt.c:(.text+0x64a87): undefined reference to
> `cipso_v4_doi_getdef' netlabel_mgmt.c:(.text+0x64c83): undefined reference
> to `cipso_v4_doi_putdef' net/built-in.o: In function
> `netlbl_cipsov4_listall':
> netlabel_cipso_v4.c:(.text+0x66e52): undefined reference to
> `cipso_v4_doi_walk' net/built-in.o: In function `netlbl_cipsov4_list':
> netlabel_cipso_v4.c:(.text+0x67199): undefined reference to
> `cipso_v4_doi_getdef' net/built-in.o: In function `netlbl_cipsov4_remove':
> netlabel_cipso_v4.c:(.text+0x6771b): undefined reference to
> `cipso_v4_doi_remove' net/built-in.o: In function
> `netlbl_cipsov4_add_pass':
> netlabel_cipso_v4.c:(.text+0x67a4b): undefined reference to
> `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x67a76): undefined reference
> to `cipso_v4_doi_free' net/built-in.o: In function
> `netlbl_cipsov4_add_local':
> netlabel_cipso_v4.c:(.text+0x67b9a): undefined reference to
> `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x67bc5): undefined reference
> to `cipso_v4_doi_free' net/built-in.o: In function
> `netlbl_cipsov4_add_std':
> netlabel_cipso_v4.c:(.text+0x68535): undefined reference to
> `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x68575): undefined reference
> to `cipso_v4_doi_free'
>
>
> Full randconfig file is attached.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* Re: [PATCH] sctp: fix CONFIG_SCTP_DBG_MSG=y null pointer dereference in sctp_v6_get_dst()
From: Neil Horman @ 2012-11-30 15:20 UTC (permalink / raw)
To: Tommi Rantala
Cc: linux-sctp, netdev, Vlad Yasevich, Sridhar Samudrala,
David S. Miller, Dave Jones
In-Reply-To: <1354267062-15888-1-git-send-email-tt.rantala@gmail.com>
On Fri, Nov 30, 2012 at 11:17:42AM +0200, Tommi Rantala wrote:
> Trinity (the syscall fuzzer) triggered the following BUG, reproducible
> only when the kernel is configured with CONFIG_SCTP_DBG_MSG=y.
>
> When CONFIG_SCTP_DBG_MSG is not set, the null pointer is never
> dereferenced.
>
> ---[ end trace a4de0bfcb38a3642 ]---
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000100
> IP: [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> PGD 4eead067 PUD 4e472067 PMD 0
> Oops: 0000 [#1] PREEMPT SMP
> Modules linked in:
> CPU 3
> Pid: 21324, comm: trinity-child11 Tainted: G W 3.7.0-rc7+ #61 ASUSTeK Computer INC. EB1012/EB1012
> RIP: 0010:[<ffffffff8136796e>] [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> RSP: 0018:ffff88004e4637a0 EFLAGS: 00010046
> RAX: ffff88004e4637da RBX: ffff88004e4637da RCX: 0000000000000000
> RDX: ffffffff8246e92a RSI: 0000000000000100 RDI: ffff88004e4637da
> RBP: ffff88004e4637a8 R08: 000000000000ffff R09: 000000000000ffff
> R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8289d600
> R13: ffffffff8289d230 R14: ffffffff8246e928 R15: ffffffff8289d600
> FS: 00007fed95153700(0000) GS:ffff88005fd80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000100 CR3: 000000004eeac000 CR4: 00000000000007e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process trinity-child11 (pid: 21324, threadinfo ffff88004e462000, task ffff8800524b0000)
> Stack:
> ffff88004e4637da ffff88004e463828 ffffffff81368eee 000000004e4637d8
> ffffffff0000ffff ffff88000000ffff 0000000000000000 000000004e4637f8
> ffffffff826285d8 ffff88004e4637f8 0000000000000000 ffff8800524b06b0
> Call Trace:
> [<ffffffff81368eee>] ip6_addr_string.isra.11+0x3e/0xa0
> [<ffffffff81369183>] pointer.isra.12+0x233/0x2d0
> [<ffffffff810a413a>] ? vprintk_emit+0x1ba/0x450
> [<ffffffff8110953d>] ? trace_hardirqs_on_caller+0x10d/0x1a0
> [<ffffffff81369757>] vsnprintf+0x187/0x5d0
> [<ffffffff81369c62>] vscnprintf+0x12/0x30
> [<ffffffff810a4028>] vprintk_emit+0xa8/0x450
> [<ffffffff81e5cb00>] printk+0x49/0x4b
> [<ffffffff81d17221>] sctp_v6_get_dst+0x731/0x780
> [<ffffffff81d16e15>] ? sctp_v6_get_dst+0x325/0x780
> [<ffffffff81d00a96>] sctp_transport_route+0x46/0x120
> [<ffffffff81cff0f1>] sctp_assoc_add_peer+0x161/0x350
> [<ffffffff81d0fd8d>] sctp_sendmsg+0x6cd/0xcb0
> [<ffffffff81b55bf0>] ? inet_create+0x670/0x670
> [<ffffffff81b55cfb>] inet_sendmsg+0x10b/0x220
> [<ffffffff81b55bf0>] ? inet_create+0x670/0x670
> [<ffffffff81a72a64>] ? sock_update_classid+0xa4/0x2b0
> [<ffffffff81a72ab0>] ? sock_update_classid+0xf0/0x2b0
> [<ffffffff81a6ac1c>] sock_sendmsg+0xdc/0xf0
> [<ffffffff8118e9e5>] ? might_fault+0x85/0x90
> [<ffffffff8118e99c>] ? might_fault+0x3c/0x90
> [<ffffffff81a6e12a>] sys_sendto+0xfa/0x130
> [<ffffffff810a9887>] ? do_setitimer+0x197/0x380
> [<ffffffff81e960d5>] ? sysret_check+0x22/0x5d
> [<ffffffff81e960a9>] system_call_fastpath+0x16/0x1b
> Code: 01 eb 89 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 f8 31 c9 48 89 e5 53 eb 12 0f 1f 40 00 48 83 c1 01 48 83 c0 04 48 83 f9 08 74 70 <0f> b6 3c 4e 89 fb 83 e7 0f c0 eb 04 41 89 d8 41 83 e0 0f 0f b6
> RIP [<ffffffff8136796e>] ip6_string+0x1e/0xa0
> RSP <ffff88004e4637a0>
> CR2: 0000000000000100
> ---[ end trace a4de0bfcb38a3643 ]---
>
> Signed-off-by: Tommi Rantala <tt.rantala@gmail.com>
> ---
> net/sctp/ipv6.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index ea14cb4..f3f0f4d 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -345,7 +345,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
> }
>
> out:
> - if (!IS_ERR(dst)) {
> + if (!IS_ERR_OR_NULL(dst)) {
> struct rt6_info *rt;
> rt = (struct rt6_info *)dst;
> t->dst = dst;
> --
> 1.7.9.5
>
>
Acked-by; Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [PATCH] smsc: RFC: Workaround for problems with lan8710 phy auto MDI-X
From: Jiri Kosina @ 2012-11-30 15:23 UTC (permalink / raw)
To: Peter Turczak
Cc: David Miller, Otavio Salvador, Javier Martinez Canillas,
Christian Hohnstaedt, netdev, linux-kernel
In-Reply-To: <8D7E9026-6276-452B-9E0C-AEB8CF38C9FD@netconsequence.de>
On Fri, 30 Nov 2012, Peter Turczak wrote:
> while debugging network outages on a customers hardware I found, that
> the MDI-X function of the lan8710 phy seemed to cause trouble. When
> connecting to almost any kind of 100/1000MBit switch, the link would
> seem to come up and data where sent out to the network. But all incoming
> packets got lost somehow. This is quite bad, as the system runs from
> nfsroot while booting up during development.
>
> When I disabled the auto MDI-X function of the phy the problem went away.
>
> Signed-off-by: Peter Turczak <pt@netconsequence.de>
> ---
> drivers/net/phy/Kconfig | 10 ++++++++++
> drivers/net/phy/smsc.c | 15 +++++++++++++++
> include/linux/smscphy.h | 5 +++++
> 3 files changed, 30 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 961f0b2..341f5aa 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -60,6 +60,16 @@ config SMSC_PHY
> ---help---
> Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
>
> +config SMSC_PHY_DISABLE_AUTOX
> + bool "Disable MDI-X upon start"
> + depends on SMSC_PHY
> + ---help---
> + When you experience problems estabishing a stable connection
> + to a network and you have e.g. a LAN8710 ethernet phy
> + this option might help you out.
> +
> + In doubt, say N
> +
I am not sure whether compile-time option for something like this is
appropriate. Kernel module parameter, perhaps?
Of course it'd be far better if faulty hardware can be autodetected in
runtime.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH net-next v1 2/2] bridge: export multicast database via netlink
From: Thomas Graf @ 2012-11-30 15:27 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, bridge, Herbert Xu, Stephen Hemminger, David S. Miller,
Jesper Dangaard Brouer
In-Reply-To: <1354287652.19865.10.camel@cr0>
On 11/30/12 at 11:00pm, Cong Wang wrote:
> I don't understand this. nla_put_flag() is used to put a flag (only one
> bit set) into a netlink message, so why should we use it to put
> p->port_no here? And why port_no 0 matters here?
nla_put_flag() will simply add a netlink attribute with no payload,
i.e. just the header. Assuming that port_no == 0 is invalid the
port_no can be used as attribute id as both are 16bit integers.
It will look like this:
MDBA_ROUTERS = {
{
.nla_len = 4,
.nla_type = <port_no_1>,
},
{
.nla_len = 4,
.nla_type = <port_no_2>,
}
[...]
}
If you ever need to extend this you can just add payload to the
per port attribute and nothing will break.
> So I should use net->dev_base_seq + mdb->seq ?
No you can't, mdb->seq is not stable throughout a dump. What you
can do is save mdb->seq in cb->args[] and in case you continue
dumping from the same mdb in the next call to your dump function
you check if it changed and bump cb->seq if it did to trigger an
interrupt.
^ permalink raw reply
* Re: linux-next: Tree for Nov 29 (netlabel)
From: Paul Moore @ 2012-11-30 15:31 UTC (permalink / raw)
To: Randy Dunlap
Cc: Stephen Rothwell, linux-next, linux-kernel,
netdev@vger.kernel.org
In-Reply-To: <3694027.VYznNcdp7C@sifl>
On Friday, November 30, 2012 10:19:16 AM Paul Moore wrote:
> On Thursday, November 29, 2012 04:05:26 PM Randy Dunlap wrote:
> > On 11/28/2012 10:40 PM, Stephen Rothwell wrote:
> > > Hi all,
> >
> > > Changes since 20121128:
> > (on i386:)
>
> If I had to guess it looks like CONFIG_NETLABEL needs to be dependent on
> CONFIG_INET. While the net/ Kconfig only pulls in the net/netlabel Kconfig
> if CONFIG_INET is defined, I'm guessing that without the explicit
> dependency there is nothing preventing someone from arriving at a bad
> configuration as we see here.
>
> Let me test this out to make sure my reasoning is right and if it is I'll
> post a patch to netdev later today.
>
> Thanks for catching this.
Hmmm. The existing logic in net/Kconfig seems to disable CONFIG_NETLABEL at
build time whenever CONFIG_INET is disabled in my .config file. The only way
I can recreate what you are seeing here is if I move the NetLabel include
outside of the INET conditional in net/Kconfig.
Regardless, adding an explicit dependency on INET to NETLABEL shouldn't hurt
anything so I'll go ahead and post the patch to netdev. Hopefully someone who
understands Kconfig better than I do can help shed some light on this.
> > net/built-in.o: In function `netlbl_cfg_cipsov4_add':
> > (.text+0x61757): undefined reference to `cipso_v4_doi_add'
> > net/built-in.o: In function `netlbl_cfg_cipsov4_del':
> > (.text+0x6177d): undefined reference to `cipso_v4_doi_remove'
> > net/built-in.o: In function `netlbl_cfg_cipsov4_map_add':
> > (.text+0x617ae): undefined reference to `cipso_v4_doi_getdef'
> > net/built-in.o: In function `netlbl_cfg_cipsov4_map_add':
> > (.text+0x61a49): undefined reference to `cipso_v4_doi_putdef'
> > net/built-in.o: In function `netlbl_sock_setattr':
> > (.text+0x6218c): undefined reference to `cipso_v4_sock_setattr'
> > net/built-in.o: In function `netlbl_sock_delattr':
> > (.text+0x6220b): undefined reference to `cipso_v4_sock_delattr'
> > net/built-in.o: In function `netlbl_sock_getattr':
> > (.text+0x62238): undefined reference to `cipso_v4_sock_getattr'
> > net/built-in.o: In function `netlbl_conn_setattr':
> > (.text+0x622de): undefined reference to `cipso_v4_sock_setattr'
> > net/built-in.o: In function `netlbl_conn_setattr':
> > (.text+0x62303): undefined reference to `cipso_v4_sock_delattr'
> > net/built-in.o: In function `netlbl_req_setattr':
> > (.text+0x62429): undefined reference to `cipso_v4_req_setattr'
> > net/built-in.o: In function `netlbl_req_setattr':
> > (.text+0x6244e): undefined reference to `cipso_v4_req_delattr'
> > net/built-in.o: In function `netlbl_req_delattr':
> > (.text+0x624ba): undefined reference to `cipso_v4_req_delattr'
> > net/built-in.o: In function `netlbl_skbuff_setattr':
> > (.text+0x62551): undefined reference to `cipso_v4_skbuff_setattr'
> > net/built-in.o: In function `netlbl_skbuff_setattr':
> > (.text+0x62576): undefined reference to `cipso_v4_skbuff_delattr'
> > net/built-in.o: In function `netlbl_skbuff_getattr':
> > (.text+0x62619): undefined reference to `cipso_v4_skbuff_getattr'
> > net/built-in.o: In function `netlbl_skbuff_err':
> > (.text+0x62685): undefined reference to `cipso_v4_error'
> > net/built-in.o: In function `netlbl_cache_invalidate':
> > (.text+0x626ab): undefined reference to `cipso_v4_cache_invalidate'
> > net/built-in.o: In function `netlbl_cache_add':
> > (.text+0x626ec): undefined reference to `cipso_v4_cache_add'
> > net/built-in.o: In function `netlbl_domhsh_remove_entry':
> > (.text+0x63294): undefined reference to `cipso_v4_doi_putdef'
> > net/built-in.o: In function `netlbl_domhsh_remove_entry':
> > (.text+0x632eb): undefined reference to `cipso_v4_doi_putdef'
> > net/built-in.o: In function `netlbl_domhsh_remove_af4':
> > (.text+0x6349b): undefined reference to `cipso_v4_doi_putdef'
> > net/built-in.o: In function `netlbl_mgmt_add_common.clone.1':
> > netlabel_mgmt.c:(.text+0x64a87): undefined reference to
> > `cipso_v4_doi_getdef' netlabel_mgmt.c:(.text+0x64c83): undefined reference
> > to `cipso_v4_doi_putdef' net/built-in.o: In function
> > `netlbl_cipsov4_listall':
> > netlabel_cipso_v4.c:(.text+0x66e52): undefined reference to
> > `cipso_v4_doi_walk' net/built-in.o: In function `netlbl_cipsov4_list':
> > netlabel_cipso_v4.c:(.text+0x67199): undefined reference to
> > `cipso_v4_doi_getdef' net/built-in.o: In function `netlbl_cipsov4_remove':
> > netlabel_cipso_v4.c:(.text+0x6771b): undefined reference to
> > `cipso_v4_doi_remove' net/built-in.o: In function
> > `netlbl_cipsov4_add_pass':
> > netlabel_cipso_v4.c:(.text+0x67a4b): undefined reference to
> > `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x67a76): undefined
> > reference
> > to `cipso_v4_doi_free' net/built-in.o: In function
> > `netlbl_cipsov4_add_local':
> > netlabel_cipso_v4.c:(.text+0x67b9a): undefined reference to
> > `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x67bc5): undefined
> > reference
> > to `cipso_v4_doi_free' net/built-in.o: In function
> > `netlbl_cipsov4_add_std':
> > netlabel_cipso_v4.c:(.text+0x68535): undefined reference to
> > `cipso_v4_doi_add' netlabel_cipso_v4.c:(.text+0x68575): undefined
> > reference
> > to `cipso_v4_doi_free'
> >
> >
> > Full randconfig file is attached.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH] net: make CONFIG_NETLABEL explicitly dependent on CONFIG_INET
From: Paul Moore @ 2012-11-30 15:35 UTC (permalink / raw)
To: netdev; +Cc: rdunlap
This should resolve an issue found during testing with random
configuration files.
net/built-in.o: In function `netlbl_cfg_cipsov4_add':
(.text+0x61757): undefined reference to `cipso_v4_doi_add'
net/built-in.o: In function `netlbl_cfg_cipsov4_del':
(.text+0x6177d): undefined reference to `cipso_v4_doi_remove'
[... and so on ...]
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Paul Moore <pmoore@redhat.com>
---
net/netlabel/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netlabel/Kconfig b/net/netlabel/Kconfig
index 56958c8..f272826 100644
--- a/net/netlabel/Kconfig
+++ b/net/netlabel/Kconfig
@@ -4,7 +4,7 @@
config NETLABEL
bool "NetLabel subsystem support"
- depends on SECURITY
+ depends on SECURITY && INET
default n
---help---
NetLabel provides support for explicit network packet labeling
^ permalink raw reply related
* Re: [net-next PATCH V2 1/9] net: frag evictor, avoid killing warm frag queues
From: Jesper Dangaard Brouer @ 2012-11-30 15:45 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, fw, netdev, pablo, tgraf, amwang, kaber, paulmck,
herbert
In-Reply-To: <1354287134.3299.67.camel@edumazet-glaptop>
On Fri, 2012-11-30 at 06:52 -0800, Eric Dumazet wrote:
> On Fri, 2012-11-30 at 11:04 +0100, Jesper Dangaard Brouer wrote:
> > So, let me instead show, with tests, that the evictor strategy is
> > broken, while keeping the original default thresh settings:
> >
> > # grep . /proc/sys/net/ipv4/ipfrag_*_thresh
> > /proc/sys/net/ipv4/ipfrag_high_thresh:262144
> > /proc/sys/net/ipv4/ipfrag_low_thresh:196608
> >
> > Test purpose, I will on a single 10G link demonstrate, that starting
> > several "N" netperf UDP fragmentation flows, will hurt performance, and
> > then claim this is caused by the bad evictor strategy.
> >
> > Test setup:
> > - Disable Ethernet flow control
> > - netperf packet size 65507
> > - Run netserver on one NUMA node
> > - Start netperf clients against a NIC on the other NUMA node
> > - (The NUMA imbalance helps the effect occur at lower N)
> >
> > Result: N=1 8040 Mbit/s
> > Result: N=2 9584 Mbit/s (4739+4845)
> > Result: N=3 4055 Mbit/s (1436+1371+1248)
> > Result: N=4 2247 Mbit/s (1538+29+54+626)
> > Result: N=5 879 Mbit/s (78+152+226+125+298)
> > Result: N=6 293 Mbit/s (85+55+32+57+46+18)
> > Result: N=7 354 Mbit/s (70+47+33+80+20+72+32)
> >
> > Can we, now, agree that the current evictor strategy is broken?!?
>
> Your setup is broken for sure.
No, its not.
> I dont know how you expect that many
> datagrams being correctly reassembled with ipfrag_high_thresh=262144
That's my point... I'm showing that its not possible, with out current
implementation!
> No matter strategy is implemented, an attacker knows it and can send
> frags so that regular workload is denied. Kernel cant decide which
> packets are more likely to be completed.
Our current evictor implementation will allow the attacker to kill ALL
frag traffic to the machine (and cause high CPU load, with CPUs
spinning).
My implementation will guarantee that some fragments will be, allowed to
finish and complete. A far better choice, than our current situation.
> BTW, install fq_codel at the sender side, so that frags are nicely
> interleaved. Because on real networks, frags of an UDP datagram rarely
> come to destination in a single train with no alien packets inside the
> train.
You are arguing in my favor. I have taken great care that my test will
interleave UDP datagrams (by CPU pinning netperf clients on the sender
side). If I just naively start all netperf client on one CPU on the
sender, then I will have packet trains... and the result will be:
Packet trains result N=5 8884 Mbit/s (1775+1775+1790+1789+1755)
That test would be "broken for sure".
^ permalink raw reply
* Re: [PATCH net-next v1 1/2] bridge: export port_no and port_id via IFA_INFO_DATA
From: Stephen Hemminger @ 2012-11-30 15:52 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, bridge, Herbert Xu, David S. Miller, Thomas Graf,
Jesper Dangaard Brouer
In-Reply-To: <1354269514-1863-1-git-send-email-amwang@redhat.com>
On Fri, 30 Nov 2012 17:58:32 +0800
Cong Wang <amwang@redhat.com> wrote:
> port_no will be used to get ifindex of a port in user-space,
> export it togather with port_id.
>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Thomas Graf <tgraf@suug.ch>
> Cc: Jesper Dangaard Brouer <brouer@redhat.com>
> Signed-off-by: Cong Wang <amwang@redhat.com>
> Acked-by: Thomas Graf <tgraf@suug.ch>
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
> include/uapi/linux/if_link.h | 2 ++
> net/bridge/br_netlink.c | 8 +++++++-
> 2 files changed, 9 insertions(+), 1 deletions(-)
>
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index bb58aeb..9cd91a9 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -218,6 +218,8 @@ enum {
> IFLA_BRPORT_MODE, /* mode (hairpin) */
> IFLA_BRPORT_GUARD, /* bpdu guard */
> IFLA_BRPORT_PROTECT, /* root port protection */
> + IFLA_BRPORT_NO, /* port no */
> + IFLA_BRPORT_ID, /* port id */
> __IFLA_BRPORT_MAX
> };
> #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index 65429b9..7b7414e 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -28,6 +28,8 @@ static inline size_t br_port_info_size(void)
> + nla_total_size(1) /* IFLA_BRPORT_MODE */
> + nla_total_size(1) /* IFLA_BRPORT_GUARD */
> + nla_total_size(1) /* IFLA_BRPORT_PROTECT */
> + + nla_total_size(2) /* IFLA_BRPORT_NO */
> + + nla_total_size(2) /* IFLA_BRPORT_ID */
> + 0;
> }
>
> @@ -53,7 +55,9 @@ static int br_port_fill_attrs(struct sk_buff *skb,
> nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) ||
> nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
> nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
> - nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)))
> + nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) ||
> + nla_put_u16(skb, IFLA_BRPORT_NO, p->port_no) ||
> + nla_put_u16(skb, IFLA_BRPORT_ID, p->port_id))
> return -EMSGSIZE;
>
> return 0;
> @@ -168,6 +172,8 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
> [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
> [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
> [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
> + [IFLA_BRPORT_NO] = { .type = NLA_U16 },
> + [IFLA_BRPORT_ID] = { .type = NLA_U16 },
> };
>
> /* Change the state of the port and notify spanning tree */
I don't think these are necessary. The device is already available and the relationship
can be determined from other messages. This is what RSTP daemon does.
^ permalink raw reply
* [PATCH 0/5] smsc95xx enhancements
From: Steve Glendinning @ 2012-11-30 15:55 UTC (permalink / raw)
To: netdev; +Cc: Steve Glendinning
This patchset is a resubmission of several patches plus two new
patches, including the expansion of cpp macros at the request of
davem.
Steve Glendinning (5):
smsc95xx: fix suspend buffer overflow
smsc95xx: fix error handling in suspend failure case
smsc95xx: don't enable remote wakeup directly
smsc95xx: fix smsc_crc return type
smsc95xx: expand check_ macros
drivers/net/usb/smsc95xx.c | 566 ++++++++++++++++++++++++++++++++------------
1 file changed, 415 insertions(+), 151 deletions(-)
--
1.7.10.4
^ 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