* [PATCH] add maintainer for network drop monitor kernel service
From: Neil Horman @ 2009-10-05 13:56 UTC (permalink / raw)
To: netdev
I was getting ribbed about this earlier, so I figured I'd make it official. Add
myself as the maintainer of the drop monitor bits, so people don't just gripe at
Dave when it breaks (I'm sure it will never break, but just in case :) ).
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 09a2028..c57c2e6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3643,6 +3643,13 @@ F: Documentation/blockdev/nbd.txt
F: drivers/block/nbd.c
F: include/linux/nbd.h
+NETWORK DROP MONITOR
+M: Neil Horman <nhorman@tuxdriver.com>
+L: netdev@vger.kernel.org
+S: Maintained
+W: https://fedorahosted.org/dropwatch/
+F: net/core/drop_monitor.c
+
NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org
^ permalink raw reply related
* Re: [PATCH net-next-2.6] bonding: remove useless assignment
From: Jiri Pirko @ 2009-10-05 14:52 UTC (permalink / raw)
To: Nicolas de Pesloüan
Cc: netdev, David Miller, Jay Vosburgh, bonding-devel
In-Reply-To: <4AB67242.6060803@free.fr>
Sun, Sep 20, 2009 at 08:19:46PM CEST, nicolas.2p.debian@free.fr wrote:
> The variable old_active is first set to bond->curr_active_slave.
> Then, it is unconditionally set to new_active, without being used in between.
>
> The first assignment, having no side effect, is useless.
Correct.
>
> Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Reviewed-by: Jiri Pirko <jpirko@redhat.com>
>
> ---
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index a7e731f..fce7233 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -1084,7 +1084,7 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
> int mintime = bond->params.updelay;
> int i;
>
> - new_active = old_active = bond->curr_active_slave;
> + new_active = bond->curr_active_slave;
>
> if (!new_active) { /* there were no active slaves left */
> if (bond->slave_cnt > 0) /* found one slave */
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [5/8,RFC] CAIF Protocol Stack
From: Stefano Babic @ 2009-10-05 15:16 UTC (permalink / raw)
To: sjur.brandeland; +Cc: netdev, Kim.xx.Lilliestierna
In-Reply-To: <1253727086-10353-1-git-send-email-sjur.brandeland@stericsson.com>
sjur.brandeland@stericsson.com wrote:
> From: Kim Lilliestierna <Kim.xx.Lilliestierna@ericsson.com>
>
> Signed-off-by: sjur.brandeland@stericsson.com
Hi Sjur,
> +obj-$(CAIF_CHRDEV) += chnl_chr.o
Probably this should be obj-$(CONFIG_CAIF_CHARDEV) += chnl_chr.o
> +
> +# Net device
> +obj-$(CAIF_NETDEV) += chnl_net.o
Should be maybe CONFIG_CAIF_NETDEV ?
Stefano
--
stefano <stefano.babic@babic.homelinux.org>
GPG Key: 0x55814DDE
Fingerprint 4E85 2A66 4CBA 497A 2A7B D3BF 5973 F216 5581 4DDE
^ permalink raw reply
* Re: [6/8,RFC] CAIF Protocol Stack
From: Stefano Babic @ 2009-10-05 15:17 UTC (permalink / raw)
To: sjur.brandeland; +Cc: netdev, Kim.xx.Lilliestierna
In-Reply-To: <1253727091-10383-1-git-send-email-sjur.brandeland@stericsson.com>
sjur.brandeland@stericsson.com wrote:
> From: Kim Lilliestierna <Kim.xx.Lilliestierna@ericsson.com>
>
> Signed-off-by: sjur.brandeland@stericsson.com
Hi Sjur,
> drivers/net/caif/chnl_tty.c | 220 +++++++++++
There is no rule in drivers/net/caif/Makefile regarding this file and it
is not mentioned in the documentation. Is there anything missing ? I
supposed the serial physical layer is implemented in phyif_ser.c.
Regards,
Stefano
--
stefano <stefano.babic@babic.homelinux.org>
GPG Key: 0x55814DDE
Fingerprint 4E85 2A66 4CBA 497A 2A7B D3BF 5973 F216 5581 4DDE
^ permalink raw reply
* [PATCH v2] net: mark net_proto_ops as const
From: Stephen Hemminger @ 2009-10-05 15:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20091004.211107.184509170.davem@davemloft.net>
All usages of structure net_proto_ops should be declared const.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
drivers/isdn/mISDN/socket.c | 3 +--
drivers/net/pppox.c | 2 +-
include/net/bluetooth/bluetooth.h | 2 +-
net/appletalk/ddp.c | 2 +-
net/atm/pvc.c | 2 +-
net/atm/svc.c | 2 +-
net/ax25/af_ax25.c | 2 +-
net/bluetooth/af_bluetooth.c | 4 ++--
net/bluetooth/bnep/sock.c | 2 +-
net/bluetooth/cmtp/sock.c | 2 +-
net/bluetooth/hci_sock.c | 2 +-
net/bluetooth/hidp/sock.c | 2 +-
net/bluetooth/l2cap.c | 2 +-
net/bluetooth/rfcomm/sock.c | 2 +-
net/bluetooth/sco.c | 2 +-
net/can/af_can.c | 2 +-
net/decnet/af_decnet.c | 2 +-
net/econet/af_econet.c | 2 +-
net/ieee802154/af_ieee802154.c | 2 +-
net/ipv4/af_inet.c | 2 +-
net/ipv6/af_inet6.c | 2 +-
net/ipx/af_ipx.c | 2 +-
net/irda/af_irda.c | 2 +-
net/iucv/af_iucv.c | 2 +-
net/key/af_key.c | 2 +-
net/llc/af_llc.c | 2 +-
net/netlink/af_netlink.c | 2 +-
net/netrom/af_netrom.c | 2 +-
net/packet/af_packet.c | 2 +-
net/phonet/af_phonet.c | 2 +-
net/rds/af_rds.c | 2 +-
net/rose/af_rose.c | 2 +-
net/rxrpc/af_rxrpc.c | 2 +-
net/unix/af_unix.c | 2 +-
net/x25/af_x25.c | 2 +-
35 files changed, 36 insertions(+), 37 deletions(-)
--- a/drivers/isdn/mISDN/socket.c 2009-10-05 08:58:02.200284285 -0700
+++ b/drivers/isdn/mISDN/socket.c 2009-10-05 08:58:12.390274786 -0700
@@ -808,8 +808,7 @@ mISDN_sock_create(struct net *net, struc
return err;
}
-static struct
-net_proto_family mISDN_sock_family_ops = {
+static const struct net_proto_family mISDN_sock_family_ops = {
.owner = THIS_MODULE,
.family = PF_ISDN,
.create = mISDN_sock_create,
--- a/drivers/net/pppox.c 2009-10-05 08:58:02.190309763 -0700
+++ b/drivers/net/pppox.c 2009-10-05 08:58:12.390274786 -0700
@@ -125,7 +125,7 @@ out:
return rc;
}
-static struct net_proto_family pppox_proto_family = {
+static const struct net_proto_family pppox_proto_family = {
.family = PF_PPPOX,
.create = pppox_create,
.owner = THIS_MODULE,
--- a/include/net/bluetooth/bluetooth.h 2009-10-05 08:58:02.210303506 -0700
+++ b/include/net/bluetooth/bluetooth.h 2009-10-05 08:58:12.390274786 -0700
@@ -121,7 +121,7 @@ struct bt_sock_list {
rwlock_t lock;
};
-int bt_sock_register(int proto, struct net_proto_family *ops);
+int bt_sock_register(int proto, const struct net_proto_family *ops);
int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
--- a/net/appletalk/ddp.c 2009-10-05 08:58:02.120299538 -0700
+++ b/net/appletalk/ddp.c 2009-10-05 08:58:12.390274786 -0700
@@ -1821,7 +1821,7 @@ static int atalk_compat_ioctl(struct soc
#endif
-static struct net_proto_family atalk_family_ops = {
+static const struct net_proto_family atalk_family_ops = {
.family = PF_APPLETALK,
.create = atalk_create,
.owner = THIS_MODULE,
--- a/net/atm/pvc.c 2009-10-05 08:58:02.030300387 -0700
+++ b/net/atm/pvc.c 2009-10-05 08:58:12.390274786 -0700
@@ -137,7 +137,7 @@ static int pvc_create(struct net *net, s
}
-static struct net_proto_family pvc_family_ops = {
+static const struct net_proto_family pvc_family_ops = {
.family = PF_ATMPVC,
.create = pvc_create,
.owner = THIS_MODULE,
--- a/net/atm/svc.c 2009-10-05 08:58:02.040304591 -0700
+++ b/net/atm/svc.c 2009-10-05 08:58:12.390274786 -0700
@@ -666,7 +666,7 @@ static int svc_create(struct net *net, s
}
-static struct net_proto_family svc_family_ops = {
+static const struct net_proto_family svc_family_ops = {
.family = PF_ATMSVC,
.create = svc_create,
.owner = THIS_MODULE,
--- a/net/ax25/af_ax25.c 2009-10-05 08:58:02.100297833 -0700
+++ b/net/ax25/af_ax25.c 2009-10-05 08:58:12.400273612 -0700
@@ -1961,7 +1961,7 @@ static const struct file_operations ax25
#endif
-static struct net_proto_family ax25_family_ops = {
+static const struct net_proto_family ax25_family_ops = {
.family = PF_AX25,
.create = ax25_create,
.owner = THIS_MODULE,
--- a/net/bluetooth/af_bluetooth.c 2009-10-05 08:58:02.180326441 -0700
+++ b/net/bluetooth/af_bluetooth.c 2009-10-05 08:58:12.400273612 -0700
@@ -45,7 +45,7 @@
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
-static struct net_proto_family *bt_proto[BT_MAX_PROTO];
+static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
static DEFINE_RWLOCK(bt_proto_lock);
static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
@@ -86,7 +86,7 @@ static inline void bt_sock_reclassify_lo
bt_key_strings[proto], &bt_lock_key[proto]);
}
-int bt_sock_register(int proto, struct net_proto_family *ops)
+int bt_sock_register(int proto, const struct net_proto_family *ops)
{
int err = 0;
--- a/net/bluetooth/bnep/sock.c 2009-10-05 08:58:02.190309763 -0700
+++ b/net/bluetooth/bnep/sock.c 2009-10-05 08:58:12.400273612 -0700
@@ -222,7 +222,7 @@ static int bnep_sock_create(struct net *
return 0;
}
-static struct net_proto_family bnep_sock_family_ops = {
+static const struct net_proto_family bnep_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = bnep_sock_create
--- a/net/bluetooth/cmtp/sock.c 2009-10-05 08:58:02.180326441 -0700
+++ b/net/bluetooth/cmtp/sock.c 2009-10-05 08:58:12.400273612 -0700
@@ -217,7 +217,7 @@ static int cmtp_sock_create(struct net *
return 0;
}
-static struct net_proto_family cmtp_sock_family_ops = {
+static const struct net_proto_family cmtp_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = cmtp_sock_create
--- a/net/bluetooth/hci_sock.c 2009-10-05 08:58:02.170284033 -0700
+++ b/net/bluetooth/hci_sock.c 2009-10-05 08:58:12.400273612 -0700
@@ -687,7 +687,7 @@ static int hci_sock_dev_event(struct not
return NOTIFY_DONE;
}
-static struct net_proto_family hci_sock_family_ops = {
+static const struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
--- a/net/bluetooth/hidp/sock.c 2009-10-05 08:58:02.160294425 -0700
+++ b/net/bluetooth/hidp/sock.c 2009-10-05 08:58:12.400273612 -0700
@@ -268,7 +268,7 @@ static int hidp_sock_create(struct net *
return 0;
}
-static struct net_proto_family hidp_sock_family_ops = {
+static const struct net_proto_family hidp_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hidp_sock_create
--- a/net/bluetooth/l2cap.c 2009-10-05 08:58:02.150281630 -0700
+++ b/net/bluetooth/l2cap.c 2009-10-05 08:58:12.400273612 -0700
@@ -3916,7 +3916,7 @@ static const struct proto_ops l2cap_sock
.getsockopt = l2cap_sock_getsockopt
};
-static struct net_proto_family l2cap_sock_family_ops = {
+static const struct net_proto_family l2cap_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = l2cap_sock_create,
--- a/net/bluetooth/rfcomm/sock.c 2009-10-05 08:58:02.170284033 -0700
+++ b/net/bluetooth/rfcomm/sock.c 2009-10-05 08:58:12.400273612 -0700
@@ -1101,7 +1101,7 @@ static const struct proto_ops rfcomm_soc
.mmap = sock_no_mmap
};
-static struct net_proto_family rfcomm_sock_family_ops = {
+static const struct net_proto_family rfcomm_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = rfcomm_sock_create
--- a/net/bluetooth/sco.c 2009-10-05 08:58:02.150281630 -0700
+++ b/net/bluetooth/sco.c 2009-10-05 08:58:12.400273612 -0700
@@ -993,7 +993,7 @@ static const struct proto_ops sco_sock_o
.getsockopt = sco_sock_getsockopt
};
-static struct net_proto_family sco_sock_family_ops = {
+static const struct net_proto_family sco_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = sco_sock_create,
--- a/net/can/af_can.c 2009-10-05 08:58:02.060274238 -0700
+++ b/net/can/af_can.c 2009-10-05 08:58:12.400273612 -0700
@@ -842,7 +842,7 @@ static struct packet_type can_packet __r
.func = can_rcv,
};
-static struct net_proto_family can_family_ops __read_mostly = {
+static const struct net_proto_family can_family_ops = {
.family = PF_CAN,
.create = can_create,
.owner = THIS_MODULE,
--- a/net/decnet/af_decnet.c 2009-10-05 08:58:02.070299326 -0700
+++ b/net/decnet/af_decnet.c 2009-10-05 08:58:12.400273612 -0700
@@ -2325,7 +2325,7 @@ static const struct file_operations dn_s
};
#endif
-static struct net_proto_family dn_family_ops = {
+static const struct net_proto_family dn_family_ops = {
.family = AF_DECnet,
.create = dn_create,
.owner = THIS_MODULE,
--- a/net/econet/af_econet.c 2009-10-05 08:58:02.040304591 -0700
+++ b/net/econet/af_econet.c 2009-10-05 08:58:12.400273612 -0700
@@ -742,7 +742,7 @@ static int econet_ioctl(struct socket *s
return 0;
}
-static struct net_proto_family econet_family_ops = {
+static const struct net_proto_family econet_family_ops = {
.family = PF_ECONET,
.create = econet_create,
.owner = THIS_MODULE,
--- a/net/ieee802154/af_ieee802154.c 2009-10-05 08:58:02.090273653 -0700
+++ b/net/ieee802154/af_ieee802154.c 2009-10-05 08:58:12.400273612 -0700
@@ -285,7 +285,7 @@ out:
return rc;
}
-static struct net_proto_family ieee802154_family_ops = {
+static const struct net_proto_family ieee802154_family_ops = {
.family = PF_IEEE802154,
.create = ieee802154_create,
.owner = THIS_MODULE,
--- a/net/ipv4/af_inet.c 2009-10-05 08:58:02.120299538 -0700
+++ b/net/ipv4/af_inet.c 2009-10-05 08:58:12.400273612 -0700
@@ -931,7 +931,7 @@ static const struct proto_ops inet_sockr
#endif
};
-static struct net_proto_family inet_family_ops = {
+static const struct net_proto_family inet_family_ops = {
.family = PF_INET,
.create = inet_create,
.owner = THIS_MODULE,
--- a/net/ipv6/af_inet6.c 2009-10-05 08:58:02.090273653 -0700
+++ b/net/ipv6/af_inet6.c 2009-10-05 08:58:12.400273612 -0700
@@ -552,7 +552,7 @@ const struct proto_ops inet6_dgram_ops =
#endif
};
-static struct net_proto_family inet6_family_ops = {
+static const struct net_proto_family inet6_family_ops = {
.family = PF_INET6,
.create = inet6_create,
.owner = THIS_MODULE,
--- a/net/ipx/af_ipx.c 2009-10-05 08:58:02.060274238 -0700
+++ b/net/ipx/af_ipx.c 2009-10-05 08:58:12.400273612 -0700
@@ -1927,7 +1927,7 @@ static int ipx_compat_ioctl(struct socke
* Socket family declarations
*/
-static struct net_proto_family ipx_family_ops = {
+static const struct net_proto_family ipx_family_ops = {
.family = PF_IPX,
.create = ipx_create,
.owner = THIS_MODULE,
--- a/net/irda/af_irda.c 2009-10-05 08:58:02.010293933 -0700
+++ b/net/irda/af_irda.c 2009-10-05 08:58:12.410362394 -0700
@@ -2463,7 +2463,7 @@ bed:
return 0;
}
-static struct net_proto_family irda_family_ops = {
+static const struct net_proto_family irda_family_ops = {
.family = PF_IRDA,
.create = irda_create,
.owner = THIS_MODULE,
--- a/net/iucv/af_iucv.c 2009-10-05 08:58:02.050336033 -0700
+++ b/net/iucv/af_iucv.c 2009-10-05 08:58:12.410362394 -0700
@@ -1715,7 +1715,7 @@ static const struct proto_ops iucv_sock_
.getsockopt = iucv_sock_getsockopt,
};
-static struct net_proto_family iucv_sock_family_ops = {
+static const struct net_proto_family iucv_sock_family_ops = {
.family = AF_IUCV,
.owner = THIS_MODULE,
.create = iucv_sock_create,
--- a/net/key/af_key.c 2009-10-05 08:58:02.070299326 -0700
+++ b/net/key/af_key.c 2009-10-05 08:58:12.410362394 -0700
@@ -3644,7 +3644,7 @@ static const struct proto_ops pfkey_ops
.recvmsg = pfkey_recvmsg,
};
-static struct net_proto_family pfkey_family_ops = {
+static const struct net_proto_family pfkey_family_ops = {
.family = PF_KEY,
.create = pfkey_create,
.owner = THIS_MODULE,
--- a/net/llc/af_llc.c 2009-10-05 08:58:02.020336899 -0700
+++ b/net/llc/af_llc.c 2009-10-05 08:58:12.410362394 -0700
@@ -1092,7 +1092,7 @@ out:
return rc;
}
-static struct net_proto_family llc_ui_family_ops = {
+static const struct net_proto_family llc_ui_family_ops = {
.family = PF_LLC,
.create = llc_ui_create,
.owner = THIS_MODULE,
--- a/net/netlink/af_netlink.c 2009-10-05 08:58:02.030300387 -0700
+++ b/net/netlink/af_netlink.c 2009-10-05 08:58:12.410362394 -0700
@@ -2050,7 +2050,7 @@ static const struct proto_ops netlink_op
.sendpage = sock_no_sendpage,
};
-static struct net_proto_family netlink_family_ops = {
+static const struct net_proto_family netlink_family_ops = {
.family = PF_NETLINK,
.create = netlink_create,
.owner = THIS_MODULE, /* for consistency 8) */
--- a/net/netrom/af_netrom.c 2009-10-05 08:58:02.110351485 -0700
+++ b/net/netrom/af_netrom.c 2009-10-05 08:58:12.410362394 -0700
@@ -1372,7 +1372,7 @@ static const struct file_operations nr_i
};
#endif /* CONFIG_PROC_FS */
-static struct net_proto_family nr_family_ops = {
+static const struct net_proto_family nr_family_ops = {
.family = PF_NETROM,
.create = nr_create,
.owner = THIS_MODULE,
--- a/net/packet/af_packet.c 2009-10-05 08:58:02.140336163 -0700
+++ b/net/packet/af_packet.c 2009-10-05 08:58:12.410362394 -0700
@@ -2363,7 +2363,7 @@ static const struct proto_ops packet_ops
.sendpage = sock_no_sendpage,
};
-static struct net_proto_family packet_family_ops = {
+static const struct net_proto_family packet_family_ops = {
.family = PF_PACKET,
.create = packet_create,
.owner = THIS_MODULE,
--- a/net/phonet/af_phonet.c 2009-10-05 08:58:02.130305908 -0700
+++ b/net/phonet/af_phonet.c 2009-10-05 08:58:12.410362394 -0700
@@ -118,7 +118,7 @@ out:
return err;
}
-static struct net_proto_family phonet_proto_family = {
+static const struct net_proto_family phonet_proto_family = {
.family = PF_PHONET,
.create = pn_socket_create,
.owner = THIS_MODULE,
--- a/net/rds/af_rds.c 2009-10-05 08:58:02.000283931 -0700
+++ b/net/rds/af_rds.c 2009-10-05 08:58:12.410362394 -0700
@@ -431,7 +431,7 @@ void rds_sock_put(struct rds_sock *rs)
sock_put(rds_rs_to_sk(rs));
}
-static struct net_proto_family rds_family_ops = {
+static const struct net_proto_family rds_family_ops = {
.family = AF_RDS,
.create = rds_create,
.owner = THIS_MODULE,
--- a/net/rose/af_rose.c 2009-10-05 08:58:02.140336163 -0700
+++ b/net/rose/af_rose.c 2009-10-05 08:58:12.410362394 -0700
@@ -1509,7 +1509,7 @@ static const struct file_operations rose
};
#endif /* CONFIG_PROC_FS */
-static struct net_proto_family rose_family_ops = {
+static const struct net_proto_family rose_family_ops = {
.family = PF_ROSE,
.create = rose_create,
.owner = THIS_MODULE,
--- a/net/rxrpc/af_rxrpc.c 2009-10-05 08:58:02.020336899 -0700
+++ b/net/rxrpc/af_rxrpc.c 2009-10-05 08:58:12.410362394 -0700
@@ -777,7 +777,7 @@ static struct proto rxrpc_proto = {
.max_header = sizeof(struct rxrpc_header),
};
-static struct net_proto_family rxrpc_family_ops = {
+static const struct net_proto_family rxrpc_family_ops = {
.family = PF_RXRPC,
.create = rxrpc_create,
.owner = THIS_MODULE,
--- a/net/unix/af_unix.c 2009-10-05 08:58:02.080273360 -0700
+++ b/net/unix/af_unix.c 2009-10-05 08:58:12.420298364 -0700
@@ -2214,7 +2214,7 @@ static const struct file_operations unix
#endif
-static struct net_proto_family unix_family_ops = {
+static const struct net_proto_family unix_family_ops = {
.family = PF_UNIX,
.create = unix_create,
.owner = THIS_MODULE,
--- a/net/x25/af_x25.c 2009-10-05 08:58:02.010293933 -0700
+++ b/net/x25/af_x25.c 2009-10-05 08:58:12.420298364 -0700
@@ -1476,7 +1476,7 @@ static int x25_ioctl(struct socket *sock
return rc;
}
-static struct net_proto_family x25_family_ops = {
+static const struct net_proto_family x25_family_ops = {
.family = AF_X25,
.create = x25_create,
.owner = THIS_MODULE,
^ permalink raw reply
* [PATCH] dcb: data center bridging ops should be r/o
From: Stephen Hemminger @ 2009-10-05 16:01 UTC (permalink / raw)
To: Jeff Kirsher, Jesse Brandeburg, David Miller; +Cc: netdev, e1000-devel
The data center bridging ops structure can be const
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/ixgbe/ixgbe.h 2009-10-03 21:40:25.712809970 -0700
+++ b/drivers/net/ixgbe/ixgbe.h 2009-10-03 21:40:33.490342038 -0700
@@ -397,7 +397,7 @@ enum ixgbe_boards {
extern struct ixgbe_info ixgbe_82598_info;
extern struct ixgbe_info ixgbe_82599_info;
#ifdef CONFIG_IXGBE_DCB
-extern struct dcbnl_rtnl_ops dcbnl_ops;
+extern const struct dcbnl_rtnl_ops dcbnl_ops;
extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
struct ixgbe_dcb_config *dst_dcb_cfg,
int tc_max);
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c 2009-10-03 21:39:54.710299317 -0700
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c 2009-10-03 21:40:05.990317034 -0700
@@ -563,7 +563,7 @@ static u8 ixgbe_dcbnl_setapp(struct net_
return rval;
}
-struct dcbnl_rtnl_ops dcbnl_ops = {
+const struct dcbnl_rtnl_ops dcbnl_ops = {
.getstate = ixgbe_dcbnl_get_state,
.setstate = ixgbe_dcbnl_set_state,
.getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
--- a/include/linux/netdevice.h 2009-10-03 21:40:52.730300256 -0700
+++ b/include/linux/netdevice.h 2009-10-03 21:41:10.362812001 -0700
@@ -909,7 +909,7 @@ struct net_device
#ifdef CONFIG_DCB
/* Data Center Bridging netlink ops */
- struct dcbnl_rtnl_ops *dcbnl_ops;
+ const struct dcbnl_rtnl_ops *dcbnl_ops;
#endif
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
^ permalink raw reply
* Re: [PATCH 1/7] mlx4: Added interrupts test support
From: Roland Dreier @ 2009-10-05 16:18 UTC (permalink / raw)
To: Yevgeny Petrilin; +Cc: davem, netdev
In-Reply-To: <4AC9D59F.1090409@mellanox.co.il>
> > Have you actually seen cases where
> > the interrupt test during initialization works but then this test
> > catches a problem? (My experience has been that if any MSI-X interrupts
> > work from a device, then they'll all work)
> It also checks that all the EQs work properly. During initialization
> we only check the asynchronous EQ
Yes, I understand what the code does. My question was whether you have
ever actually observed a case where the async EQ works but another EQ
doesn't? In other words is this test useful in practice?
- R.
^ permalink raw reply
* Re: [PATCH] Wireless / ath5k: Simplify suspend and resume callbacks
From: Luis R. Rodriguez @ 2009-10-05 16:21 UTC (permalink / raw)
To: Rafael J. Wysocki, netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
ath5k-devel-xDcbHBWguxEUs3QNXV6qNA, John W. Linville, LKML,
pm list
In-Reply-To: <200910050052.09085.rjw-KKrjLPT3xs0@public.gmane.org>
On Sun, Oct 4, 2009 at 10:52 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> Simplify the suspend and resume callbacks of ath5k by converting the
> driver to struct dev_pm_ops and allowing the PCI PM core to do the
> PCI-specific suspend/resume handling.
>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Do you happen to know if the new dev_pm_ops thing handle WOL / WoW [1]?
[1] http://wireless.kernel.org/en/users/Documentation/WoW
> #ifdef CONFIG_PM
> -static int
> -ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
> +static int ath5k_pci_suspend(struct device *dev)
> {
> - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
> + struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
> struct ath5k_softc *sc = hw->priv;
>
> ath5k_led_off(sc);
> -
> - pci_save_state(pdev);
> - pci_disable_device(pdev);
For WoW right here we'd do
pci_prepare_to_sleep(pdev) and bail out.
> - pci_set_power_state(pdev, PCI_D3hot);
And here we'd call something like this:
pci_wake_from_d3(pdev, !!sc->wow_triggers_enabled);
> -
> return 0;
> }
Are all drivers being converted?
It'll be a while before we get WoW enabled on ath5k but it is
technically possible, the work was tested for ath9k back in July [2]
but I never submitted this to be merged due to some inconsistent
issues I was noticing with the hardware.
[2] http://kernel.org/pub/linux/kernel/people/mcgrof/patches/wow-07-21.patch
Luis
_______________________________________________
ath5k-devel mailing list
ath5k-devel@lists.ath5k.org
https://lists.ath5k.org/mailman/listinfo/ath5k-devel
^ permalink raw reply
* Re: [7/8,RFC] CAIF Protocol Stack
From: Stefano Babic @ 2009-10-05 16:22 UTC (permalink / raw)
To: sjur.brandeland; +Cc: netdev, Kim.xx.Lilliestierna
In-Reply-To: <1253727096-10413-1-git-send-email-sjur.brandeland@stericsson.com>
sjur.brandeland@stericsson.com wrote:
> From: Kim Lilliestierna <Kim.xx.Lilliestierna@ericsson.com>
>
> Signed-off-by: sjur.brandeland@stericsson.com
Hi Sjur,
> +A configuration tool chardevconfig exist in order to simplify
> +creation of CAIF Channels (typically used from init scripts).
> +E.g:
> +
> + $chardevconfig /dev/caifconfig -
> + CREATE TYPE=AT NAME=chnlat1 DEVTYPE=CHAR ^D
It seems that this command requires additional parameters as PRIO and
PHYPREF, else a "parse error" is reported by the tool.
> +GenCaif is a generic CAIF protocol implementation. It implements the CAIF
> +protocol as specified in "CAIF Protocol Specification" (155 19-CRH 109 913).
Is this one an internal document or was it published and is available
for reading ?
> diff --git a/Documentation/CAIF/README b/Documentation/CAIF/README
> new file mode 100644
> index 0000000..aa04150
> --- /dev/null
> +++ b/Documentation/CAIF/README
> @@ -0,0 +1,60 @@
> +copyright (C) ST-Ericsson AB 2009
> +Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
> + Kim Lilliestierna Kim.xx.Lilliestierna@ericsson.com
> +License terms: GNU General Public License (GPL), version 2.
> +
> +=== Start ===
> +Copy the .ko files onto the board, and do insmod:
> +
> +insmod caif.ko
> +insmod phyif_msl.ko
Is phyif_msl.ko obsolete ? There is no track of the corresponding source
file.
> +=== Preparing the setup.===
> +
> +Make sure that the kernel is built with module support.
> +
> +There are some things that need to be
> +tweaked to get the host TTY correctly setup to talk to the modem.
> +Since the CAIF stack is running in the kernel and we want to use the existing
> +TTY we are installing our physical serial driver as a line discipline above
> +the TTY device.
I wanted to test your patches and I tried to follow your description,
but I have some problems to connect the tty-layer with the physical uart
linux driver.
I use a different architecture - ARM (ARM9) based and I applied your
patches on a 2.6.29 kernel. I agree, I should apply them on the top of
2.6.31 as you tested, but it seems I have a configuration problem not
related to the kernel version.
I can see that CAIF wants to try to enumerate the devices
(cfctrl_enum_req is called) and then the phyif_ser module is called
(ser_phy_tx, as supposed). But then the systems hangs in the write loop
and the uart transmit function of the linux serial driver is never called.
To setup the system, if I really understood well, I followed the steps:
$ modprobe caif
$ modprobe phyif_ser
$ echo 6 > /sys/class/caif/dbg_lvl
$ ./ldiscd
caifdev_phy_register: phy:bf00fb68 id:1
caifdev_phy_register: bf00fb68 ID 1 == 1
$ modprobe chnl_chr
<caif_chrinit_module:1142, TRACE>
Compiled:Oct 5 2009:14:08:17
-bash-3.2# ./chardevconfig /dev/caifconfig -
CREATE TYPE=AT NAME=chnlat10 DEVTYPE=CHAR PHYPREF=LAT PRIO=HI
caifdev_open: Entered
caifdev_ioctl: Entered
<print_device_list:664, TRACE> List of devices:
<print_device_list:674, TRACE> list is empty
<chrdev_create:1005, TRACE> [chrdev_create:1005] dev=c3ab4800
<chrdev_create:1051, TRACE> [chrdev_create:1051] pktf=c3ab495c
<chrdev_create:1053, TRACE> [chrdev_create:1053] cfpkt_create_xmit=bf005bf4
<chrdev_create:1061, TRACE> dev: Registered dev with name=chnlat10
minor=52, dev=c3a65180
<print_device_list:664, TRACE> List of devices:
<print_device_list:670, TRACE> i = 0, minor= 52, name = chnlat10, open = 0
caifdev_release: Entered
Create device: name = chnlat10, major = 10, minor = 52
So it seems the device is correctly created.
Then I tried:
echo -e "AT\r\n" > /dev/chnlat10
<print_device_list:664, TRACE> List of devices:
<print_device_list:670, TRACE> i = 0, minor= 52, name = chnlat10, open = 0
<find_device:627, TRACE> [find_device:627] start looping
<find_device:632, TRACE> [find_device:632] check 52,52, chnlat10, <NULL>
<find_device:646, TRACE> [find_device:646] match 52, <NULL>
<caif_chropen:721, TRACE> [caif_chropen:721] dev=c3ab4800
and the system hangs. I could find after some instrumentation that the
system hangs in the ser_phy_tx function. This is not a surprise, because
the Uart TX function is never called. Have I missed something ?
Best regards,
Stefano Babic
--
stefano <stefano.babic@babic.homelinux.org>
GPG Key: 0x55814DDE
Fingerprint 4E85 2A66 4CBA 497A 2A7B D3BF 5973 F216 5581 4DDE
^ permalink raw reply
* [net-next-2.6 PATCH 01/15] igb: remove unused temp variable from stats clearing path
From: Jeff Kirsher @ 2009-10-05 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
From: Alexander Duyck <alexander.h.duyck@intel.com>
There is a temp variable in the stats clearing path that isn't needed since
the results from the stats read can be immediately discared. Since it
isn't needed we might as well just drop it from the function call.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 96 ++++++++++++++++++++---------------------
drivers/net/igb/e1000_mac.c | 76 ++++++++++++++++----------------
2 files changed, 84 insertions(+), 88 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index f8f5772..b60daf4 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1181,61 +1181,59 @@ static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
**/
static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
{
- u32 temp;
-
igb_clear_hw_cntrs_base(hw);
- temp = rd32(E1000_PRC64);
- temp = rd32(E1000_PRC127);
- temp = rd32(E1000_PRC255);
- temp = rd32(E1000_PRC511);
- temp = rd32(E1000_PRC1023);
- temp = rd32(E1000_PRC1522);
- temp = rd32(E1000_PTC64);
- temp = rd32(E1000_PTC127);
- temp = rd32(E1000_PTC255);
- temp = rd32(E1000_PTC511);
- temp = rd32(E1000_PTC1023);
- temp = rd32(E1000_PTC1522);
-
- temp = rd32(E1000_ALGNERRC);
- temp = rd32(E1000_RXERRC);
- temp = rd32(E1000_TNCRS);
- temp = rd32(E1000_CEXTERR);
- temp = rd32(E1000_TSCTC);
- temp = rd32(E1000_TSCTFC);
-
- temp = rd32(E1000_MGTPRC);
- temp = rd32(E1000_MGTPDC);
- temp = rd32(E1000_MGTPTC);
-
- temp = rd32(E1000_IAC);
- temp = rd32(E1000_ICRXOC);
-
- temp = rd32(E1000_ICRXPTC);
- temp = rd32(E1000_ICRXATC);
- temp = rd32(E1000_ICTXPTC);
- temp = rd32(E1000_ICTXATC);
- temp = rd32(E1000_ICTXQEC);
- temp = rd32(E1000_ICTXQMTC);
- temp = rd32(E1000_ICRXDMTC);
-
- temp = rd32(E1000_CBTMPC);
- temp = rd32(E1000_HTDPMC);
- temp = rd32(E1000_CBRMPC);
- temp = rd32(E1000_RPTHC);
- temp = rd32(E1000_HGPTC);
- temp = rd32(E1000_HTCBDPC);
- temp = rd32(E1000_HGORCL);
- temp = rd32(E1000_HGORCH);
- temp = rd32(E1000_HGOTCL);
- temp = rd32(E1000_HGOTCH);
- temp = rd32(E1000_LENERRS);
+ rd32(E1000_PRC64);
+ rd32(E1000_PRC127);
+ rd32(E1000_PRC255);
+ rd32(E1000_PRC511);
+ rd32(E1000_PRC1023);
+ rd32(E1000_PRC1522);
+ rd32(E1000_PTC64);
+ rd32(E1000_PTC127);
+ rd32(E1000_PTC255);
+ rd32(E1000_PTC511);
+ rd32(E1000_PTC1023);
+ rd32(E1000_PTC1522);
+
+ rd32(E1000_ALGNERRC);
+ rd32(E1000_RXERRC);
+ rd32(E1000_TNCRS);
+ rd32(E1000_CEXTERR);
+ rd32(E1000_TSCTC);
+ rd32(E1000_TSCTFC);
+
+ rd32(E1000_MGTPRC);
+ rd32(E1000_MGTPDC);
+ rd32(E1000_MGTPTC);
+
+ rd32(E1000_IAC);
+ rd32(E1000_ICRXOC);
+
+ rd32(E1000_ICRXPTC);
+ rd32(E1000_ICRXATC);
+ rd32(E1000_ICTXPTC);
+ rd32(E1000_ICTXATC);
+ rd32(E1000_ICTXQEC);
+ rd32(E1000_ICTXQMTC);
+ rd32(E1000_ICRXDMTC);
+
+ rd32(E1000_CBTMPC);
+ rd32(E1000_HTDPMC);
+ rd32(E1000_CBRMPC);
+ rd32(E1000_RPTHC);
+ rd32(E1000_HGPTC);
+ rd32(E1000_HTCBDPC);
+ rd32(E1000_HGORCL);
+ rd32(E1000_HGORCH);
+ rd32(E1000_HGOTCL);
+ rd32(E1000_HGOTCH);
+ rd32(E1000_LENERRS);
/* This register should not be read in copper configurations */
if (hw->phy.media_type == e1000_media_type_internal_serdes ||
igb_sgmii_active_82575(hw))
- temp = rd32(E1000_SCVPC);
+ rd32(E1000_SCVPC);
}
/**
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 7d76bb0..986aa90 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -399,45 +399,43 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
**/
void igb_clear_hw_cntrs_base(struct e1000_hw *hw)
{
- u32 temp;
-
- temp = rd32(E1000_CRCERRS);
- temp = rd32(E1000_SYMERRS);
- temp = rd32(E1000_MPC);
- temp = rd32(E1000_SCC);
- temp = rd32(E1000_ECOL);
- temp = rd32(E1000_MCC);
- temp = rd32(E1000_LATECOL);
- temp = rd32(E1000_COLC);
- temp = rd32(E1000_DC);
- temp = rd32(E1000_SEC);
- temp = rd32(E1000_RLEC);
- temp = rd32(E1000_XONRXC);
- temp = rd32(E1000_XONTXC);
- temp = rd32(E1000_XOFFRXC);
- temp = rd32(E1000_XOFFTXC);
- temp = rd32(E1000_FCRUC);
- temp = rd32(E1000_GPRC);
- temp = rd32(E1000_BPRC);
- temp = rd32(E1000_MPRC);
- temp = rd32(E1000_GPTC);
- temp = rd32(E1000_GORCL);
- temp = rd32(E1000_GORCH);
- temp = rd32(E1000_GOTCL);
- temp = rd32(E1000_GOTCH);
- temp = rd32(E1000_RNBC);
- temp = rd32(E1000_RUC);
- temp = rd32(E1000_RFC);
- temp = rd32(E1000_ROC);
- temp = rd32(E1000_RJC);
- temp = rd32(E1000_TORL);
- temp = rd32(E1000_TORH);
- temp = rd32(E1000_TOTL);
- temp = rd32(E1000_TOTH);
- temp = rd32(E1000_TPR);
- temp = rd32(E1000_TPT);
- temp = rd32(E1000_MPTC);
- temp = rd32(E1000_BPTC);
+ rd32(E1000_CRCERRS);
+ rd32(E1000_SYMERRS);
+ rd32(E1000_MPC);
+ rd32(E1000_SCC);
+ rd32(E1000_ECOL);
+ rd32(E1000_MCC);
+ rd32(E1000_LATECOL);
+ rd32(E1000_COLC);
+ rd32(E1000_DC);
+ rd32(E1000_SEC);
+ rd32(E1000_RLEC);
+ rd32(E1000_XONRXC);
+ rd32(E1000_XONTXC);
+ rd32(E1000_XOFFRXC);
+ rd32(E1000_XOFFTXC);
+ rd32(E1000_FCRUC);
+ rd32(E1000_GPRC);
+ rd32(E1000_BPRC);
+ rd32(E1000_MPRC);
+ rd32(E1000_GPTC);
+ rd32(E1000_GORCL);
+ rd32(E1000_GORCH);
+ rd32(E1000_GOTCL);
+ rd32(E1000_GOTCH);
+ rd32(E1000_RNBC);
+ rd32(E1000_RUC);
+ rd32(E1000_RFC);
+ rd32(E1000_ROC);
+ rd32(E1000_RJC);
+ rd32(E1000_TORL);
+ rd32(E1000_TORH);
+ rd32(E1000_TOTL);
+ rd32(E1000_TOTH);
+ rd32(E1000_TPR);
+ rd32(E1000_TPT);
+ rd32(E1000_MPTC);
+ rd32(E1000_BPTC);
}
/**
^ permalink raw reply related
* [net-next-2.6 PATCH 02/15] igb: update comments for serdes config and update to handle duplex
From: Jeff Kirsher @ 2009-10-05 16:31 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This update corrects the driver so that it handles duplex for serdes links
correctly instead of just forcing full duplex always.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 55 ++++++++++++++++++++++++++++-------------
drivers/net/igb/e1000_82575.h | 1 +
drivers/net/igb/e1000_hw.h | 1 +
3 files changed, 40 insertions(+), 17 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index b60daf4..5604b3e 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -706,9 +706,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
s32 ret_val;
u16 speed, duplex;
- /* SGMII link check is done through the PCS register. */
- if ((hw->phy.media_type != e1000_media_type_copper) ||
- (igb_sgmii_active_82575(hw))) {
+ if (hw->phy.media_type != e1000_media_type_copper) {
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
&duplex);
/*
@@ -723,6 +721,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
return ret_val;
}
+
/**
* igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
* @hw: pointer to the HW structure
@@ -788,13 +787,23 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
{
u32 reg;
+ u16 eeprom_data = 0;
if (hw->phy.media_type != e1000_media_type_internal_serdes ||
igb_sgmii_active_82575(hw))
return;
- /* if the management interface is not enabled, then power down */
- if (!igb_enable_mng_pass_thru(hw)) {
+ if (hw->bus.func == E1000_FUNC_0)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ else if (hw->bus.func == E1000_FUNC_1)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+
+ /*
+ * If APM is not enabled in the EEPROM and management interface is
+ * not enabled, then power down.
+ */
+ if (!(eeprom_data & E1000_NVM_APME_82575) &&
+ !igb_enable_mng_pass_thru(hw)) {
/* Disable PCS to turn off link */
reg = rd32(E1000_PCS_CFG0);
reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -1010,10 +1019,13 @@ out:
}
/**
- * igb_setup_serdes_link_82575 - Setup link for fiber/serdes
+ * igb_setup_serdes_link_82575 - Setup link for serdes
* @hw: pointer to the HW structure
*
- * Configures speed and duplex for fiber and serdes links.
+ * Configure the physical coding sub-layer (PCS) link. The PCS link is
+ * used on copper connections where the serialized gigabit media independent
+ * interface (sgmii), or serdes fiber is being used. Configures the link
+ * for auto-negotiation or forces speed/duplex.
**/
static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
{
@@ -1086,18 +1098,27 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
*/
if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
/* Set PCS register for autoneg */
- reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
- E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
- E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
- E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
+ reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
+ E1000_PCS_LCTL_FDV_FULL | /* SerDes Full dplx */
+ E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
+ E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
} else {
- /* Set PCS register for forced speed */
- reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
- E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
- E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
- E1000_PCS_LCTL_FSD | /* Force Speed */
- E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
+ /* Check for duplex first */
+ if (hw->mac.forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
+ reg |= E1000_PCS_LCTL_FDV_FULL;
+
+ /* No need to check for 1000/full since the spec states that
+ * it requires autoneg to be enabled */
+ /* Now set speed */
+ if (hw->mac.forced_speed_duplex & E1000_ALL_100_SPEED)
+ reg |= E1000_PCS_LCTL_FSV_100;
+
+ /* Force speed and force link */
+ reg |= E1000_PCS_LCTL_FSD |
+ E1000_PCS_LCTL_FORCE_LINK |
+ E1000_PCS_LCTL_FLV_LINK_UP;
+
hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
}
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index ebd146f..7be3a0b 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -167,6 +167,7 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 119869b..b1e0c06 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -50,6 +50,7 @@ struct e1000_hw;
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
+#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
enum e1000_mac_type {
^ permalink raw reply related
* [net-next-2.6 PATCH 03/15] igb: update the approach taken to acquiring and releasing the phy lock
From: Jeff Kirsher @ 2009-10-05 16:32 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
The current approach is just using a ?: type mechanism to set the phy
locking bit. This if fine for now but limits us to only 2. Switch to a
nested if statement for future compatiblity with more than 2 phys.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 5604b3e..65b9000 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -240,9 +240,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
**/
static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
{
- u16 mask;
+ u16 mask = E1000_SWFW_PHY0_SM;
- mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+ if (hw->bus.func == E1000_FUNC_1)
+ mask = E1000_SWFW_PHY1_SM;
return igb_acquire_swfw_sync_82575(hw, mask);
}
@@ -256,9 +257,11 @@ static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
**/
static void igb_release_phy_82575(struct e1000_hw *hw)
{
- u16 mask;
+ u16 mask = E1000_SWFW_PHY0_SM;
+
+ if (hw->bus.func == E1000_FUNC_1)
+ mask = E1000_SWFW_PHY1_SM;
- mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
igb_release_swfw_sync_82575(hw, mask);
}
^ permalink raw reply related
* [net-next-2.6 PATCH 04/15] igb: add locking to reads of the i2c interface
From: Jeff Kirsher @ 2009-10-05 16:32 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
The current implementation of sgmii support isn't correctly locking the
interfaces for reads/writes. This change pulls the read/write
functionality out of 82575.c and moves it to phy.c. In addition it
replaces the implementation in 82575.c with one that uses locking around
the relocated i2c interface calls.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 85 ++++++++----------------------------
drivers/net/igb/e1000_phy.c | 97 +++++++++++++++++++++++++++++++++++++++++
drivers/net/igb/e1000_phy.h | 2 +
3 files changed, 119 insertions(+), 65 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 65b9000..7897181 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -277,45 +277,23 @@ static void igb_release_phy_82575(struct e1000_hw *hw)
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data)
{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, i2ccmd = 0;
+ s32 ret_val = -E1000_ERR_PARAM;
if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
hw_dbg("PHY Address %u is out of range\n", offset);
- return -E1000_ERR_PARAM;
+ goto out;
}
- /*
- * Set up Op-code, Phy Address, and register address in the I2CCMD
- * register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
- (E1000_I2CCMD_OPCODE_READ));
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ goto out;
- wr32(E1000_I2CCMD, i2ccmd);
+ ret_val = igb_read_phy_reg_i2c(hw, offset, data);
- /* Poll the ready bit to see if the I2C read completed */
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- udelay(50);
- i2ccmd = rd32(E1000_I2CCMD);
- if (i2ccmd & E1000_I2CCMD_READY)
- break;
- }
- if (!(i2ccmd & E1000_I2CCMD_READY)) {
- hw_dbg("I2CCMD Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (i2ccmd & E1000_I2CCMD_ERROR) {
- hw_dbg("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
-
- /* Need to byte-swap the 16-bit value. */
- *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
+ hw->phy.ops.release(hw);
- return 0;
+out:
+ return ret_val;
}
/**
@@ -330,47 +308,24 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 data)
{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, i2ccmd = 0;
- u16 phy_data_swapped;
+ s32 ret_val = -E1000_ERR_PARAM;
+
if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
hw_dbg("PHY Address %d is out of range\n", offset);
- return -E1000_ERR_PARAM;
+ goto out;
}
- /* Swap the data bytes for the I2C interface */
- phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ goto out;
- /*
- * Set up Op-code, Phy Address, and register address in the I2CCMD
- * register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
- (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
- E1000_I2CCMD_OPCODE_WRITE |
- phy_data_swapped);
-
- wr32(E1000_I2CCMD, i2ccmd);
-
- /* Poll the ready bit to see if the I2C read completed */
- for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
- udelay(50);
- i2ccmd = rd32(E1000_I2CCMD);
- if (i2ccmd & E1000_I2CCMD_READY)
- break;
- }
- if (!(i2ccmd & E1000_I2CCMD_READY)) {
- hw_dbg("I2CCMD Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (i2ccmd & E1000_I2CCMD_ERROR) {
- hw_dbg("I2CCMD Error bit set\n");
- return -E1000_ERR_PHY;
- }
+ ret_val = igb_write_phy_reg_i2c(hw, offset, data);
- return 0;
+ hw->phy.ops.release(hw);
+
+out:
+ return ret_val;
}
/**
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index ee46060..d4c928c 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -239,6 +239,103 @@ out:
}
/**
+ * igb_read_phy_reg_i2c - Read PHY register using i2c
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Reads the PHY register at offset using the i2c interface and stores the
+ * retrieved information in data.
+ **/
+s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ u32 i, i2ccmd = 0;
+
+
+ /*
+ * Set up Op-code, Phy Address, and register address in the I2CCMD
+ * register. The MAC will take care of interfacing with the
+ * PHY to retrieve the desired data.
+ */
+ i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+ (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
+ (E1000_I2CCMD_OPCODE_READ));
+
+ wr32(E1000_I2CCMD, i2ccmd);
+
+ /* Poll the ready bit to see if the I2C read completed */
+ for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+ udelay(50);
+ i2ccmd = rd32(E1000_I2CCMD);
+ if (i2ccmd & E1000_I2CCMD_READY)
+ break;
+ }
+ if (!(i2ccmd & E1000_I2CCMD_READY)) {
+ hw_dbg("I2CCMD Read did not complete\n");
+ return -E1000_ERR_PHY;
+ }
+ if (i2ccmd & E1000_I2CCMD_ERROR) {
+ hw_dbg("I2CCMD Error bit set\n");
+ return -E1000_ERR_PHY;
+ }
+
+ /* Need to byte-swap the 16-bit value. */
+ *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
+
+ return 0;
+}
+
+/**
+ * igb_write_phy_reg_i2c - Write PHY register using i2c
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Writes the data to PHY register at the offset using the i2c interface.
+ **/
+s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ u32 i, i2ccmd = 0;
+ u16 phy_data_swapped;
+
+
+ /* Swap the data bytes for the I2C interface */
+ phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
+
+ /*
+ * Set up Op-code, Phy Address, and register address in the I2CCMD
+ * register. The MAC will take care of interfacing with the
+ * PHY to retrieve the desired data.
+ */
+ i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+ (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
+ E1000_I2CCMD_OPCODE_WRITE |
+ phy_data_swapped);
+
+ wr32(E1000_I2CCMD, i2ccmd);
+
+ /* Poll the ready bit to see if the I2C read completed */
+ for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+ udelay(50);
+ i2ccmd = rd32(E1000_I2CCMD);
+ if (i2ccmd & E1000_I2CCMD_READY)
+ break;
+ }
+ if (!(i2ccmd & E1000_I2CCMD_READY)) {
+ hw_dbg("I2CCMD Write did not complete\n");
+ return -E1000_ERR_PHY;
+ }
+ if (i2ccmd & E1000_I2CCMD_ERROR) {
+ hw_dbg("I2CCMD Error bit set\n");
+ return -E1000_ERR_PHY;
+ }
+
+ return 0;
+}
+
+/**
* igb_read_phy_reg_igp - Read igp PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index ebe4b61..4c49803 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -61,6 +61,8 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
+s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
+s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
^ permalink raw reply related
* [net-next-2.6 PATCH 06/15] igb: make use of the uta to allow for promiscous mode filter
From: Jeff Kirsher @ 2009-10-05 16:33 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
In order to support functions such as vlan tag stripping when SR-IOV is
enabled any given packet must match at least one filter. However in the
case of promiscous mode being enabled on the PF the traffic routed to it
may not match any filters and is just sent to the PF by default. In order
to make certain that this traffic is processed we can set all bits in the
UTA registers to create a pseudo promiscous mode filter that accepts all
packets.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 5 +
drivers/net/igb/e1000_hw.h | 1
drivers/net/igb/e1000_regs.h | 1
drivers/net/igb/igb_main.c | 203 ++++++++++++++++++++++++++++++++---------
4 files changed, 163 insertions(+), 47 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 7897181..b8a88a8 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -875,6 +875,11 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
for (i = 0; i < mac->mta_reg_count; i++)
array_wr32(E1000_MTA, i, 0);
+ /* Zero out the Unicast HASH table */
+ hw_dbg("Zeroing the UTA\n");
+ for (i = 0; i < mac->uta_reg_count; i++)
+ array_wr32(E1000_UTA, i, 0);
+
/* Setup link and flow control */
ret_val = igb_setup_link(hw);
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index b1e0c06..7b7898b 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -340,6 +340,7 @@ struct e1000_mac_info {
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
+ u16 uta_reg_count;
/* Maximum size of the MTA register table in all supported adapters */
#define MAX_MTA_REG 128
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 345d144..76c3389 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -331,6 +331,7 @@ enum {
#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
+#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
/* These act per VF so an array friendly macro is used */
#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index bb0aacd..fdbe332 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -106,6 +106,7 @@ static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
static struct net_device_stats *igb_get_stats(struct net_device *);
static int igb_change_mtu(struct net_device *, int);
static int igb_set_mac(struct net_device *, void *);
+static void igb_set_uta(struct igb_adapter *adapter);
static irqreturn_t igb_intr(int irq, void *);
static irqreturn_t igb_intr_msi(int irq, void *);
static irqreturn_t igb_msix_other(int irq, void *);
@@ -141,7 +142,6 @@ static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
reg_data = rd32(E1000_VMOLR(vfn));
reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */
- E1000_VMOLR_ROPE | /* Accept packets matched in UTA */
E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */
E1000_VMOLR_AUPE | /* Accept untagged packets */
E1000_VMOLR_STRVLAN; /* Strip vlan tags */
@@ -2286,6 +2286,9 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Set the default pool for the PF's first queue */
igb_configure_vt_default_pool(adapter);
+ /* set UTA to appropriate mode */
+ igb_set_uta(adapter);
+
/* set the correct pool for the PF default MAC address in entry 0 */
igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
adapter->vfs_allocated_count);
@@ -2521,44 +2524,72 @@ static int igb_set_mac(struct net_device *netdev, void *p)
}
/**
- * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * igb_write_mc_addr_list - write multicast addresses to MTA
* @netdev: network interface device structure
*
- * The set_rx_mode entry point is called whenever the unicast or multicast
- * address lists or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper unicast, multicast,
- * promiscuous mode, and all-multi behavior.
+ * Writes multicast address list to the MTA hash table.
+ * Returns: -ENOMEM on failure
+ * 0 on no addresses written
+ * X on writing X addresses to MTA
**/
-static void igb_set_rx_mode(struct net_device *netdev)
+static int igb_write_mc_addr_list(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- unsigned int rar_entries = hw->mac.rar_entry_count -
- (adapter->vfs_allocated_count + 1);
struct dev_mc_list *mc_ptr = netdev->mc_list;
- u8 *mta_list = NULL;
- u32 rctl;
+ u8 *mta_list;
+ u32 vmolr = 0;
int i;
- /* Check for Promiscuous and All Multicast modes */
- rctl = rd32(E1000_RCTL);
+ if (!netdev->mc_count) {
+ /* nothing to program, so clear mc list */
+ igb_update_mc_addr_list(hw, NULL, 0);
+ igb_restore_vf_multicasts(adapter);
+ return 0;
+ }
- if (netdev->flags & IFF_PROMISC) {
- rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- rctl &= ~E1000_RCTL_VFE;
- } else {
- if (netdev->flags & IFF_ALLMULTI)
- rctl |= E1000_RCTL_MPE;
- else
- rctl &= ~E1000_RCTL_MPE;
+ mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+ if (!mta_list)
+ return -ENOMEM;
- if (netdev->uc.count > rar_entries)
- rctl |= E1000_RCTL_UPE;
- else
- rctl &= ~E1000_RCTL_UPE;
- rctl |= E1000_RCTL_VFE;
+ /* set vmolr receive overflow multicast bit */
+ vmolr |= E1000_VMOLR_ROMPE;
+
+ /* The shared function expects a packed array of only addresses. */
+ mc_ptr = netdev->mc_list;
+
+ for (i = 0; i < netdev->mc_count; i++) {
+ if (!mc_ptr)
+ break;
+ memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
+ mc_ptr = mc_ptr->next;
}
- wr32(E1000_RCTL, rctl);
+ igb_update_mc_addr_list(hw, mta_list, i);
+ kfree(mta_list);
+
+ return netdev->mc_count;
+}
+
+/**
+ * igb_write_uc_addr_list - write unicast addresses to RAR table
+ * @netdev: network interface device structure
+ *
+ * Writes unicast address list to the RAR table.
+ * Returns: -ENOMEM on failure/insufficient address space
+ * 0 on no addresses written
+ * X on writing X addresses to the RAR table
+ **/
+static int igb_write_uc_addr_list(struct net_device *netdev)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned int vfn = adapter->vfs_allocated_count;
+ unsigned int rar_entries = hw->mac.rar_entry_count - (vfn + 1);
+ int count = 0;
+
+ /* return ENOMEM indicating insufficient memory for addresses */
+ if (netdev->uc.count > rar_entries)
+ return -ENOMEM;
if (netdev->uc.count && rar_entries) {
struct netdev_hw_addr *ha;
@@ -2567,7 +2598,8 @@ static void igb_set_rx_mode(struct net_device *netdev)
break;
igb_rar_set_qsel(adapter, ha->addr,
rar_entries--,
- adapter->vfs_allocated_count);
+ vfn);
+ count++;
}
}
/* write the addresses in reverse order to avoid write combining */
@@ -2577,29 +2609,79 @@ static void igb_set_rx_mode(struct net_device *netdev)
}
wrfl();
- if (!netdev->mc_count) {
- /* nothing to program, so clear mc list */
- igb_update_mc_addr_list(hw, NULL, 0);
- igb_restore_vf_multicasts(adapter);
- return;
+ return count;
+}
+
+/**
+ * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igb_set_rx_mode(struct net_device *netdev)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned int vfn = adapter->vfs_allocated_count;
+ u32 rctl, vmolr = 0;
+ int count;
+
+ /* Check for Promiscuous and All Multicast modes */
+ rctl = rd32(E1000_RCTL);
+
+ /* clear the effected bits */
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
+
+ if (netdev->flags & IFF_PROMISC) {
+ rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+ vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
+ } else {
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ vmolr |= E1000_VMOLR_MPME;
+ } else {
+ /*
+ * Write addresses to the MTA, if the attempt fails
+ * then we should just turn on promiscous mode so
+ * that we can at least receive multicast traffic
+ */
+ count = igb_write_mc_addr_list(netdev);
+ if (count < 0) {
+ rctl |= E1000_RCTL_MPE;
+ vmolr |= E1000_VMOLR_MPME;
+ } else if (count) {
+ vmolr |= E1000_VMOLR_ROMPE;
+ }
+ }
+ /*
+ * Write addresses to available RAR registers, if there is not
+ * sufficient space to store all the addresses then enable
+ * unicast promiscous mode
+ */
+ count = igb_write_uc_addr_list(netdev);
+ if (count < 0) {
+ rctl |= E1000_RCTL_UPE;
+ vmolr |= E1000_VMOLR_ROPE;
+ }
+ rctl |= E1000_RCTL_VFE;
}
+ wr32(E1000_RCTL, rctl);
- mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
- if (!mta_list) {
- dev_err(&adapter->pdev->dev,
- "failed to allocate multicast filter list\n");
+ /*
+ * In order to support SR-IOV and eventually VMDq it is necessary to set
+ * the VMOLR to enable the appropriate modes. Without this workaround
+ * we will have issues with VLAN tag stripping not being done for frames
+ * that are only arriving because we are the default pool
+ */
+ if (hw->mac.type < e1000_82576)
return;
- }
- /* The shared function expects a packed array of only addresses. */
- for (i = 0; i < netdev->mc_count; i++) {
- if (!mc_ptr)
- break;
- memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
- mc_ptr = mc_ptr->next;
- }
- igb_update_mc_addr_list(hw, mta_list, i);
- kfree(mta_list);
+ vmolr |= rd32(E1000_VMOLR(vfn)) &
+ ~(E1000_VMOLR_ROPE | E1000_VMOLR_MPME | E1000_VMOLR_ROMPE);
+ wr32(E1000_VMOLR(vfn), vmolr);
igb_restore_vf_multicasts(adapter);
}
@@ -4264,6 +4346,33 @@ static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
}
/**
+ * igb_set_uta - Set unicast filter table address
+ * @adapter: board private structure
+ *
+ * The unicast table address is a register array of 32-bit registers.
+ * The table is meant to be used in a way similar to how the MTA is used
+ * however due to certain limitations in the hardware it is necessary to
+ * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscous
+ * enable bit to allow vlan tag stripping when promiscous mode is enabled
+ **/
+static void igb_set_uta(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int i;
+
+ /* The UTA table only exists on 82576 hardware and newer */
+ if (hw->mac.type < e1000_82576)
+ return;
+
+ /* we only need to do this if VMDq is enabled */
+ if (!adapter->vfs_allocated_count)
+ return;
+
+ for (i = 0; i < hw->mac.uta_reg_count; i++)
+ array_wr32(E1000_UTA, i, ~0);
+}
+
+/**
* igb_intr_msi - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
^ permalink raw reply related
* [net-next-2.6 PATCH 05/15] igb: add combined function for setting rar and pool bits
From: Jeff Kirsher @ 2009-10-05 16:32 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds igb_rar_qsel which sets the mac address and pool bits for a
given mac address in the receive address register table.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 63 ++++++++++++++++++++++++++++----------------
1 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 714c3a4..bb0aacd 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -127,10 +127,10 @@ static void igb_vlan_rx_register(struct net_device *, struct vlan_group *);
static void igb_vlan_rx_add_vid(struct net_device *, u16);
static void igb_vlan_rx_kill_vid(struct net_device *, u16);
static void igb_restore_vlan(struct igb_adapter *);
+static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);
static void igb_ping_all_vfs(struct igb_adapter *);
static void igb_msg_task(struct igb_adapter *);
static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
static void igb_vmm_control(struct igb_adapter *);
static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
@@ -168,16 +168,6 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
return 0;
}
-static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
-{
- u32 reg_data;
-
- reg_data = rd32(E1000_RAH(entry));
- reg_data &= ~E1000_RAH_POOL_MASK;
- reg_data |= E1000_RAH_POOL_1 << pool;;
- wr32(E1000_RAH(entry), reg_data);
-}
-
#ifdef CONFIG_PM
static int igb_suspend(struct pci_dev *, pm_message_t);
static int igb_resume(struct pci_dev *);
@@ -982,7 +972,6 @@ int igb_up(struct igb_adapter *adapter)
igb_configure_msix(adapter);
igb_vmm_control(adapter);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
/* Clear any pending interrupts. */
@@ -1769,7 +1758,6 @@ static int igb_open(struct net_device *netdev)
igb_configure(adapter);
igb_vmm_control(adapter);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
err = igb_request_irq(adapter);
@@ -2298,6 +2286,10 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Set the default pool for the PF's first queue */
igb_configure_vt_default_pool(adapter);
+ /* set the correct pool for the PF default MAC address in entry 0 */
+ igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
+ adapter->vfs_allocated_count);
+
igb_rlpml_set(adapter);
/* Enable Receives */
@@ -2521,8 +2513,9 @@ static int igb_set_mac(struct net_device *netdev, void *p)
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
- igb_rar_set(hw, hw->mac.addr, 0);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ /* set the correct pool for the new PF MAC address in entry 0 */
+ igb_rar_set_qsel(adapter, hw->mac.addr, 0,
+ adapter->vfs_allocated_count);
return 0;
}
@@ -2572,10 +2565,9 @@ static void igb_set_rx_mode(struct net_device *netdev)
list_for_each_entry(ha, &netdev->uc.list, list) {
if (!rar_entries)
break;
- igb_rar_set(hw, ha->addr, rar_entries);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count,
- rar_entries);
- rar_entries--;
+ igb_rar_set_qsel(adapter, ha->addr,
+ rar_entries--,
+ adapter->vfs_allocated_count);
}
}
/* write the addresses in reverse order to avoid write combining */
@@ -4142,8 +4134,7 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
igb_vf_reset_event(adapter, vf);
/* set vf mac address */
- igb_rar_set(hw, vf_mac, rar_entry);
- igb_set_rah_pool(hw, vf, rar_entry);
+ igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf);
/* enable transmit and receive for vf */
reg = rd32(E1000_VFTE);
@@ -5532,6 +5523,33 @@ static void igb_io_resume(struct pci_dev *pdev)
igb_get_hw_control(adapter);
}
+static void igb_rar_set_qsel(struct igb_adapter *adapter, u8 *addr, u32 index,
+ u8 qsel)
+{
+ u32 rar_low, rar_high;
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* HW expects these in little endian so we reverse the byte order
+ * from network order (big endian) to little endian
+ */
+ rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
+ ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+ rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+
+ /* Indicate to hardware the Address is Valid. */
+ rar_high |= E1000_RAH_AV;
+
+ if (hw->mac.type == e1000_82575)
+ rar_high |= E1000_RAH_POOL_1 * qsel;
+ else
+ rar_high |= E1000_RAH_POOL_1 << qsel;
+
+ wr32(E1000_RAL(index), rar_low);
+ wrfl();
+ wr32(E1000_RAH(index), rar_high);
+ wrfl();
+}
+
static int igb_set_vf_mac(struct igb_adapter *adapter,
int vf, unsigned char *mac_addr)
{
@@ -5542,8 +5560,7 @@ static int igb_set_vf_mac(struct igb_adapter *adapter,
memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
- igb_rar_set(hw, mac_addr, rar_entry);
- igb_set_rah_pool(hw, vf, rar_entry);
+ igb_rar_set_qsel(adapter, mac_addr, rar_entry, vf);
return 0;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 07/15] igb: add support for 82576NS SerDes adapter
From: Jeff Kirsher @ 2009-10-05 16:33 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds the device ID necessary to support the 82576NS SerDes
adapter.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 1 +
drivers/net/igb/e1000_hw.h | 1 +
drivers/net/igb/igb_main.c | 1 +
3 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index b8a88a8..e07f66c 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -81,6 +81,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
break;
case E1000_DEV_ID_82576:
case E1000_DEV_ID_82576_NS:
+ case E1000_DEV_ID_82576_NS_SERDES:
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
case E1000_DEV_ID_82576_QUAD_COPPER:
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 7b7898b..4e7850d 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -42,6 +42,7 @@ struct e1000_hw;
#define E1000_DEV_ID_82576_SERDES 0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82576_NS 0x150A
+#define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index fdbe332..83c0837 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -63,6 +63,7 @@ static const struct e1000_info *igb_info_tbl[] = {
static struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
^ permalink raw reply related
* [net-next-2.6 PATCH 08/15] igb: add function to handle mailbox lock
From: Jeff Kirsher @ 2009-10-05 16:33 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
Both the read and write mailbox functions need to acquire the mailbox lock.
Since that is the case we might as well combine both of the procedures into
one function so it is easier to maintain.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mbx.c | 63 +++++++++++++++++++++++--------------------
1 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index ed9058e..ef645f6 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -305,6 +305,30 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
}
/**
+ * igb_obtain_mbx_lock_pf - obtain mailbox lock
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+ u32 p2v_mailbox;
+
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* reserve mailbox for vf use */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
+ ret_val = 0;
+
+ return ret_val;
+}
+
+/**
* igb_write_mbx_pf - Places a message in the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
@@ -316,27 +340,17 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
- u32 p2v_mailbox;
- s32 ret_val = 0;
+ s32 ret_val;
u16 i;
- /* Take ownership of the buffer */
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
- /* Make sure we have ownership now... */
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
- /* failed to grab ownership */
- ret_val = -E1000_ERR_MBX;
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+ if (ret_val)
goto out_no_write;
- }
- /*
- * flush any ack or msg which may already be in the queue
- * as they are likely the result of an error
- */
- igb_check_for_ack_pf(hw, vf_number);
+ /* flush msg and acks as we are overwriting the message buffer */
igb_check_for_msg_pf(hw, vf_number);
+ igb_check_for_ack_pf(hw, vf_number);
/* copy the caller specified message to the mailbox memory buffer */
for (i = 0; i < size; i++)
@@ -367,20 +381,13 @@ out_no_write:
static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
- u32 p2v_mailbox;
- s32 ret_val = 0;
+ s32 ret_val;
u16 i;
- /* Take ownership of the buffer */
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
- /* Make sure we have ownership now... */
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
- /* failed to grab ownership */
- ret_val = -E1000_ERR_MBX;
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+ if (ret_val)
goto out_no_read;
- }
/* copy the message to the mailbox memory buffer */
for (i = 0; i < size; i++)
@@ -392,8 +399,6 @@ static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
/* update stats */
hw->mbx.stats.msgs_rx++;
- ret_val = 0;
-
out_no_read:
return ret_val;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 09/15] igb: fix a few items where weren't correctly setup for mbx timeout
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
The mailbox timeout routines need to be updated as they were not correctly
handling the case of a mailbox timeout and could cause issues with long
delays when used.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mbx.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index ef645f6..c474cdb 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -143,12 +143,16 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
if (!countdown || !mbx->ops.check_for_msg)
goto out;
- while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
@@ -168,12 +172,16 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
if (!countdown || !mbx->ops.check_for_ack)
goto out;
- while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
@@ -217,12 +225,13 @@ out:
static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = 0;
+ s32 ret_val = -E1000_ERR_MBX;
- if (!mbx->ops.write)
+ /* exit if either we can't write or there isn't a defined timeout */
+ if (!mbx->ops.write || !mbx->timeout)
goto out;
- /* send msg*/
+ /* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
/* if msg sent wait until we receive an ack */
^ permalink raw reply related
* [net-next-2.6 PATCH 10/15] igb: change how we handle alternate mac addresses
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch allows us to treat the alternate mac address as though it is the
physical address on the adapter. This is accomplished by letting the
alt_mac_address function to only fail on an NVM error. If no errors occur
and the alternate mac address is not present then RAR0 is read as the
default mac address.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 13 +++++++++++--
drivers/net/igb/e1000_hw.h | 2 ++
drivers/net/igb/e1000_mac.c | 17 +++++++++--------
3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index e07f66c..45063c2 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1152,9 +1152,18 @@ static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
{
s32 ret_val = 0;
- if (igb_check_alt_mac_addr(hw))
- ret_val = igb_read_mac_addr(hw);
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = igb_check_alt_mac_addr(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = igb_read_mac_addr(hw);
+out:
return ret_val;
}
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 4e7850d..fad7cf5 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -54,6 +54,8 @@ struct e1000_hw;
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
+
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 986aa90..4969a5b 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
}
if (nvm_alt_mac_addr_offset == 0xFFFF) {
- ret_val = -(E1000_NOT_IMPLEMENTED);
+ /* There is no Alternate MAC Address */
goto out;
}
if (hw->bus.func == E1000_FUNC_1)
- nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16);
-
+ nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
for (i = 0; i < ETH_ALEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
@@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
/* if multicast bit is set, the alternate address will not be used */
if (alt_mac_addr[0] & 0x01) {
- ret_val = -(E1000_NOT_IMPLEMENTED);
+ hw_dbg("Ignoring Alternate Mac Address with MC bit set\n");
goto out;
}
- for (i = 0; i < ETH_ALEN; i++)
- hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
-
- hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
+ /*
+ * We have a valid alternate MAC address, and we want to treat it the
+ * same as the normal permanent MAC address stored by the HW into the
+ * RAR. Do this by mapping this address into RAR0.
+ */
+ hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
out:
return ret_val;
^ permalink raw reply related
* [net-next-2.6 PATCH 11/15] igb: remove microwire support from igb
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
igb doesn't have any devices that use a microwire interface for NVM. As
such the code related to this can be removed.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_hw.h | 3 ---
drivers/net/igb/e1000_nvm.c | 36 +++---------------------------------
2 files changed, 3 insertions(+), 36 deletions(-)
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index fad7cf5..2dc9294 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -74,7 +74,6 @@ enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
- e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
};
@@ -83,8 +82,6 @@ enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
- e1000_nvm_override_microwire_small,
- e1000_nvm_override_microwire_large
};
enum e1000_phy_type {
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index a88bfe2..d83b77f 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -78,9 +78,7 @@ static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
u32 mask;
mask = 0x01 << (count - 1);
- if (nvm->type == e1000_nvm_eeprom_microwire)
- eecd &= ~E1000_EECD_DO;
- else if (nvm->type == e1000_nvm_eeprom_spi)
+ if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
@@ -220,22 +218,7 @@ static void igb_standby_nvm(struct e1000_hw *hw)
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
- if (nvm->type == e1000_nvm_eeprom_microwire) {
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- wr32(E1000_EECD, eecd);
- wrfl();
- udelay(nvm->delay_usec);
-
- igb_raise_eec_clk(hw, &eecd);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- wr32(E1000_EECD, eecd);
- wrfl();
- udelay(nvm->delay_usec);
-
- igb_lower_eec_clk(hw, &eecd);
- } else if (nvm->type == e1000_nvm_eeprom_spi) {
+ if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
@@ -263,12 +246,6 @@ static void e1000_stop_nvm(struct e1000_hw *hw)
/* Pull CS high */
eecd |= E1000_EECD_CS;
igb_lower_eec_clk(hw, &eecd);
- } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
- /* CS on Microcwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
- wr32(E1000_EECD, eecd);
- igb_raise_eec_clk(hw, &eecd);
- igb_lower_eec_clk(hw, &eecd);
}
}
@@ -304,14 +281,7 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
u8 spi_stat_reg;
- if (nvm->type == e1000_nvm_eeprom_microwire) {
- /* Clear SK and DI */
- eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
- wr32(E1000_EECD, eecd);
- /* Set CS */
- eecd |= E1000_EECD_CS;
- wr32(E1000_EECD, eecd);
- } else if (nvm->type == e1000_nvm_eeprom_spi) {
+ if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
^ permalink raw reply related
* [net-next-2.6 PATCH 12/15] igb: move the generic copper link setup code into e1000_phy.c
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch moves the generic portion of the copper link setup into a
seperate function in e1000_phy.c. This helps to reduce the size of
copper_link_setup_82575 and make it a bit more readable.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 40 +--------------------------
drivers/net/igb/e1000_phy.c | 61 ++++++++++++++++++++++++++++++++++++++++-
drivers/net/igb/e1000_phy.h | 2 +
3 files changed, 62 insertions(+), 41 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 45063c2..5d345e3 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -907,7 +907,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
{
u32 ctrl;
s32 ret_val;
- bool link;
ctrl = rd32(E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
@@ -940,44 +939,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
if (ret_val)
goto out;
- if (hw->mac.autoneg) {
- /*
- * Setup autoneg and flow control advertisement
- * and perform autonegotiation.
- */
- ret_val = igb_copper_link_autoneg(hw);
- if (ret_val)
- goto out;
- } else {
- /*
- * PHY will be set to 10H, 10F, 100H or 100F
- * depending on user settings.
- */
- hw_dbg("Forcing Speed and Duplex\n");
- ret_val = hw->phy.ops.force_speed_duplex(hw);
- if (ret_val) {
- hw_dbg("Error Forcing Speed and Duplex\n");
- goto out;
- }
- }
-
- /*
- * Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
- if (ret_val)
- goto out;
-
- if (link) {
- hw_dbg("Valid link established!!!\n");
- /* Config the MAC and PHY after link is up */
- igb_config_collision_dist(hw);
- ret_val = igb_config_fc_after_link_up(hw);
- } else {
- hw_dbg("Unable to establish link!!!\n");
- }
-
+ ret_val = igb_setup_copper_link(hw);
out:
return ret_val;
}
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index d4c928c..b27275d 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -669,7 +669,7 @@ out:
* and restart the negotiation process between the link partner. If
* autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
**/
-s32 igb_copper_link_autoneg(struct e1000_hw *hw)
+static s32 igb_copper_link_autoneg(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
@@ -893,6 +893,65 @@ out:
}
/**
+ * igb_setup_copper_link - Configure copper link settings
+ * @hw: pointer to the HW structure
+ *
+ * Calls the appropriate function to configure the link for auto-neg or forced
+ * speed and duplex. Then we check for link, once link is established calls
+ * to configure collision distance and flow control are called. If link is
+ * not established, we return -E1000_ERR_PHY (-2).
+ **/
+s32 igb_setup_copper_link(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ bool link;
+
+
+ if (hw->mac.autoneg) {
+ /*
+ * Setup autoneg and flow control advertisement and perform
+ * autonegotiation.
+ */
+ ret_val = igb_copper_link_autoneg(hw);
+ if (ret_val)
+ goto out;
+ } else {
+ /*
+ * PHY will be set to 10H, 10F, 100H or 100F
+ * depending on user settings.
+ */
+ hw_dbg("Forcing Speed and Duplex\n");
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
+ if (ret_val) {
+ hw_dbg("Error Forcing Speed and Duplex\n");
+ goto out;
+ }
+ }
+
+ /*
+ * Check link status. Wait up to 100 microseconds for link to become
+ * valid.
+ */
+ ret_val = igb_phy_has_link(hw,
+ COPPER_LINK_UP_LIMIT,
+ 10,
+ &link);
+ if (ret_val)
+ goto out;
+
+ if (link) {
+ hw_dbg("Valid link established!!!\n");
+ igb_config_collision_dist(hw);
+ ret_val = igb_config_fc_after_link_up(hw);
+ } else {
+ hw_dbg("Unable to establish link!!!\n");
+ }
+
+out:
+ return ret_val;
+}
+
+/**
* igb_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 4c49803..adb9436 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -43,7 +43,6 @@ enum e1000_smart_speed {
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
-s32 igb_copper_link_autoneg(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
@@ -57,6 +56,7 @@ s32 igb_phy_sw_reset(struct e1000_hw *hw);
s32 igb_phy_hw_reset(struct e1000_hw *hw);
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
+s32 igb_setup_copper_link(struct e1000_hw *hw);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
^ permalink raw reply related
* [net-next-2.6 PATCH 13/15] igb: add code to retry a phy read in the event of failure on link check
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds a retry to phy reads in the event of failure. The original
code broke out of the loop on failure and this is a mistake as we should be
trying to do the read twice.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_phy.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index b27275d..5fe03e1 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1444,8 +1444,14 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
* it across the board.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
+ if (ret_val) {
+ /*
+ * If the first read fails, another entity may have
+ * ownership of the resources, wait and try again to
+ * see if they have relinquished the resources yet.
+ */
+ udelay(usec_interval);
+ }
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
^ permalink raw reply related
* [net-next-2.6 PATCH 14/15] igb: add additional error handling to the phy code
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This update adds additional exception handling to the phy code to handle
situations where it may be called incorrectly. In addition it adds some
bounds checking to the cable length checks to prevent an array overrun in
the event that the hardware returned a different value than expected.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_phy.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 5fe03e1..83b706c 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -39,6 +39,9 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+ (sizeof(e1000_m88_cable_length_table) / \
+ sizeof(e1000_m88_cable_length_table[0]))
static const u16 e1000_igp_2_cable_length_table[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -109,7 +112,10 @@ out:
**/
static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = 0;
+
+ if (!(hw->phy.ops.write_reg))
+ goto out;
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
if (ret_val)
@@ -1059,22 +1065,19 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
igb_phy_force_speed_duplex_setup(hw, &phy_data);
- /* Reset the phy to commit changes. */
- phy_data |= MII_CR_RESET;
-
ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
- udelay(1);
+ /* Reset the phy to commit changes. */
+ ret_val = igb_phy_sw_reset(hw);
+ if (ret_val)
+ goto out;
if (phy->autoneg_wait_to_complete) {
hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
- ret_val = igb_phy_has_link(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
+ ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
if (ret_val)
goto out;
@@ -1084,8 +1087,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* Reset the DSP and cross our fingers.
*/
ret_val = phy->ops.write_reg(hw,
- M88E1000_PHY_PAGE_SELECT,
- 0x001d);
+ M88E1000_PHY_PAGE_SELECT,
+ 0x001d);
if (ret_val)
goto out;
ret_val = igb_phy_reset_dsp(hw);
@@ -1095,7 +1098,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
/* Try once more */
ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
- 100000, &link);
+ 100000, &link);
if (ret_val)
goto out;
}
@@ -1207,9 +1210,12 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = 0;
u16 data;
+ if (!(hw->phy.ops.read_reg))
+ goto out;
+
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
@@ -1495,8 +1501,13 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw)
index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+ if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+ phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
^ permalink raw reply related
* [net-next-2.6 PATCH 15/15] igb: add flushes between RAR writes when setting mac address
From: Jeff Kirsher @ 2009-10-05 16:36 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
There are some switches that will do write combining when they see two
sequential regions written. In order to avoid any possible write combining
issues it is necessary to add a flush after writing each piece of a rar
register.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mac.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 4969a5b..2ad358a 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -247,8 +247,15 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
+ /*
+ * Some bridges will combine consecutive 32-bit writes into
+ * a single burst write, which will malfunction on some parts.
+ * The flushes avoid this.
+ */
wr32(E1000_RAL(index), rar_low);
+ wrfl();
wr32(E1000_RAH(index), rar_high);
+ wrfl();
}
/**
^ permalink raw reply related
* Re: [net-next-2.6 PATCH 6/9] vxge: Check if FCS stripping is disabled by the firmware.
From: Ben Greear @ 2009-10-05 16:44 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Sreenivasa Honnur, davem, netdev, support
In-Reply-To: <4AC9EEE0.5000601@gmail.com>
On 10/05/2009 06:04 AM, Eric Dumazet wrote:
> Sreenivasa Honnur a écrit :
>> - Added a function to check if FCS stripping is disabled by the firmware, if
>> it is not disabled fail driver load.
>>
>> - By default FCS stripping is disabled by the firmware. With this assumption
>> driver decrements the indicated packet length by 4 bytes(FCS length).
>>
>> - This patch ensures that FCS stripping is disabled during driver load time.
>>
>> Signed-off-by: Sreenivasa Honnur<sreenivasa.honnur@neterion.com>
>
> What the big deal about FCS not being stripped ?
I'd consider it a feature to be able to receive the CRC...would be nice for
sniffing applications!
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ 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