* Re: DDoS attack causing bad effect on conntrack searches
From: Patrick McHardy @ 2010-04-23 10:56 UTC (permalink / raw)
To: Eric Dumazet
Cc: Changli Gao, hawk, Linux Kernel Network Hackers, netfilter-devel,
Paul E McKenney
In-Reply-To: <1271946961.7895.5665.camel@edumazet-laptop>
Eric Dumazet wrote:
> Le jeudi 22 avril 2010 à 15:17 +0200, Patrick McHardy a écrit :
>> Changli Gao wrote:
>>>> struct nf_conntrack_tuple_hash *
>>>> __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
>>>> ...
>>> We should add a retry limit there.
>> We can't do that since that would allow false negatives.
>
> If one hash slot is under attack, then there is a bug somewhere.
>
> If we cannot avoid this, we can fallback to a secure mode at the second
> retry, and take the spinlock.
>
> Tis way, most of lookups stay lockless (one pass), and some might take
> the slot lock to avoid the possibility of a loop.
That sounds like a good idea. But lets what for Jesper's test results
before we start fixing this problem :)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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
* [PATCH net-next-2.6] l2tp_eth: fix memory allocation
From: Jiri Pirko @ 2010-04-23 11:01 UTC (permalink / raw)
To: netdev; +Cc: davem, kleptog, jchapman
Since .size is set properly in "struct pernet_operations l2tp_eth_net_ops",
allocating space for "struct l2tp_eth_net" by hand is not correct, even causes
memory leakage.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index ca1164a..58c6c4c 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -276,43 +276,16 @@ out:
static __net_init int l2tp_eth_init_net(struct net *net)
{
- struct l2tp_eth_net *pn;
- int err;
-
- pn = kzalloc(sizeof(*pn), GFP_KERNEL);
- if (!pn)
- return -ENOMEM;
+ struct l2tp_eth_net *pn = net_generic(net, l2tp_eth_net_id);
INIT_LIST_HEAD(&pn->l2tp_eth_dev_list);
spin_lock_init(&pn->l2tp_eth_lock);
- err = net_assign_generic(net, l2tp_eth_net_id, pn);
- if (err)
- goto out;
-
return 0;
-
-out:
- kfree(pn);
- return err;
-}
-
-static __net_exit void l2tp_eth_exit_net(struct net *net)
-{
- struct l2tp_eth_net *pn;
-
- pn = net_generic(net, l2tp_eth_net_id);
- /*
- * if someone has cached our net then
- * further net_generic call will return NULL
- */
- net_assign_generic(net, l2tp_eth_net_id, NULL);
- kfree(pn);
}
static __net_initdata struct pernet_operations l2tp_eth_net_ops = {
.init = l2tp_eth_init_net,
- .exit = l2tp_eth_exit_net,
.id = &l2tp_eth_net_id,
.size = sizeof(struct l2tp_eth_net),
};
^ permalink raw reply related
* Re: DDoS attack causing bad effect on conntrack searches
From: Eric Dumazet @ 2010-04-23 11:05 UTC (permalink / raw)
To: Patrick McHardy
Cc: Jesper Dangaard Brouer, paulmck, Changli Gao, hawk,
Linux Kernel Network Hackers, Netfilter Developers
In-Reply-To: <4BD17CAA.4090708@trash.net>
Le vendredi 23 avril 2010 à 12:55 +0200, Patrick McHardy a écrit :
> Eric Dumazet wrote:
> >
> > OK but a lookup last a fraction of a micro second, unless interrupted by
> > hard irq.
> >
> > Probability of a change during a lookup should be very very small.
> >
> > Note that the scenario for a restart is :
> >
> > The lookup go through the chain.
> > While it is examining one object, this object is deleted.
> > The object is re-allocated by another cpu and inserted to a new chain.
>
> I think another scenario that seems a bit more likely would be
> that a new entry is added to the chain after it was fully searched.
> Perhaps we could continue searching at the last position if the
> last entry is not a nulls entry to improve this.
But the last entry is always a nulls entry, what do you mean exactly ?
When an unsert (of a fresh object, not a reused one) is done, this
doesnt affect lookups in any way, since its done at the head of list.
^ permalink raw reply
* Re: DDoS attack causing bad effect on conntrack searches
From: Eric Dumazet @ 2010-04-23 11:06 UTC (permalink / raw)
To: Patrick McHardy
Cc: Jesper Dangaard Brouer, paulmck, Changli Gao, hawk,
Linux Kernel Network Hackers, Netfilter Developers
In-Reply-To: <4BD1784A.6010306@trash.net>
Le vendredi 23 avril 2010 à 12:36 +0200, Patrick McHardy a écrit :
> Eric Dumazet wrote:
> > Le jeudi 22 avril 2010 à 23:03 +0200, Eric Dumazet a écrit :
> >>> Guess I have to reproduce the DoS attack in a testlab (I will first have
> >>> time Tuesday). So we can determine if its bad hashing or restart of the
> >>> search loop.
> >>>
> >
> > Or very long chains, if attacker managed to find a jhash flaw.
>
> That should be visible in the "searched" statistic.
>
> > You could add a lookup_restart counter :
>
> I've applied Jespers equivalent patch.
Yes of course, I missed it or I would not have cooked it ;)
Thanks
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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: DDoS attack causing bad effect on conntrack searches
From: Patrick McHardy @ 2010-04-23 11:06 UTC (permalink / raw)
To: Eric Dumazet
Cc: Jesper Dangaard Brouer, paulmck, Changli Gao, hawk,
Linux Kernel Network Hackers, Netfilter Developers
In-Reply-To: <1272020717.7895.7974.camel@edumazet-laptop>
Eric Dumazet wrote:
> Le vendredi 23 avril 2010 à 12:55 +0200, Patrick McHardy a écrit :
>> Eric Dumazet wrote:
>>> OK but a lookup last a fraction of a micro second, unless interrupted by
>>> hard irq.
>>>
>>> Probability of a change during a lookup should be very very small.
>>>
>>> Note that the scenario for a restart is :
>>>
>>> The lookup go through the chain.
>>> While it is examining one object, this object is deleted.
>>> The object is re-allocated by another cpu and inserted to a new chain.
>> I think another scenario that seems a bit more likely would be
>> that a new entry is added to the chain after it was fully searched.
>> Perhaps we could continue searching at the last position if the
>> last entry is not a nulls entry to improve this.
>
> But the last entry is always a nulls entry, what do you mean exactly ?
>
> When an unsert (of a fresh object, not a reused one) is done, this
> doesnt affect lookups in any way, since its done at the head of list.
Right, I missed that :)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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
* [PATCH/RFC Resubmission] cdc_ether: Identify MBM devices by GUID in MDLM descriptor
From: Jonas Sjoquist @ 2010-04-23 11:07 UTC (permalink / raw)
To: oneukum, davem; +Cc: netdev
From: Jonas Sjöquist <jonas.sjoquist@ericsson.com>
This patch removes vid/pid for Ericsson MBM devices from the whitelist set of
devices. The MBM devices are instead identified by GUID.
In order for cdc_ether to handle these devices the GUID in the MDLM descriptor
is tested. All MBM devices currently handled by cdc_ether as well as future
CDC Ethernet MBM devices can be identified by the GUID.
This is the same solution used in Carl Nordbeck's mbm driver,
http://kerneltrap.org/mailarchive/linux-usb/2008/11/17/4141384/thread
I post this as RFC to get feedback on however cdc_ether is the correct place to
do the binding, or if it should be done in a separate driver, e.g. zaurus.
Signed-off-by: Jonas Sjöquist <jonas.sjoquist@ericsson.com>
---
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index c8cdb7f..811b2dc 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -64,6 +64,11 @@ static int is_wireless_rndis(struct usb_interface_descriptor *desc)
#endif
+static const u8 mbm_guid[16] = {
+ 0xa3, 0x17, 0xa8, 0x8b, 0x04, 0x5e, 0x4f, 0x01,
+ 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
+};
+
/*
* probes control interface, claims data interface, collects the bulk
* endpoints, activates data interface (if needed), maybe sets MTU.
@@ -79,6 +84,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
int status;
int rndis;
struct usb_driver *driver = driver_of(intf);
+ struct usb_cdc_mdlm_desc *desc = NULL;
+ struct usb_cdc_mdlm_detail_desc *detail = NULL;
if (sizeof dev->data < sizeof *info)
return -EDOM;
@@ -229,6 +236,34 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
* side link address we were given.
*/
break;
+ case USB_CDC_MDLM_TYPE:
+ if (desc) {
+ dev_dbg(&intf->dev, "extra MDLM descriptor\n");
+ goto bad_desc;
+ }
+
+ desc = (void *)buf;
+
+ if (desc->bLength != sizeof(*desc))
+ goto bad_desc;
+
+ if (memcmp(&desc->bGUID, mbm_guid, 16))
+ goto bad_desc;
+ break;
+ case USB_CDC_MDLM_DETAIL_TYPE:
+ if (detail) {
+ dev_dbg(&intf->dev, "extra MDLM detail descriptor\n");
+ goto bad_desc;
+ }
+
+ detail = (void *)buf;
+
+ if (detail->bGuidDescriptorType == 0) {
+ if (detail->bLength < (sizeof(*detail) + 1))
+ goto bad_desc;
+ } else
+ goto bad_desc;
+ break;
}
next_desc:
len -= buf [0]; /* bLength */
@@ -542,80 +577,10 @@ static const struct usb_device_id products [] = {
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
}, {
- /* Ericsson F3507g */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3507g ver. 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3607gw */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3607gw ver 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3607gw ver 3 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3307 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson F3307 ver 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson C3607w */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Ericsson C3607w ver 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Toshiba F3507g */
- USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Toshiba F3607gw */
- USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Toshiba F3607gw ver 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Dell F3507g */
- USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Dell F3607gw */
- USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
-}, {
- /* Dell F3607gw ver 2 */
- USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM,
- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &mbm_info,
+ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&mbm_info,
+
},
{ }, // END
};
^ permalink raw reply related
* [PATCH net-next-2.6] net: disallow to use net_assign_generic externally
From: Jiri Pirko @ 2010-04-23 11:40 UTC (permalink / raw)
To: netdev; +Cc: davem, ebiederm
Now there's no need to use this fuction directly because it's handled by
register_pernet_device. So to make this simple and easy to understand,
make this static to do not tempt potentional users.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h
index ff4982a..81a31c0 100644
--- a/include/net/netns/generic.h
+++ b/include/net/netns/generic.h
@@ -14,11 +14,8 @@
* The rules are simple:
* 1. set pernet_operations->id. After register_pernet_device you
* will have the id of your private pointer.
- * 2. Either set pernet_operations->size (to have the code allocate and
- * free a private structure pointed to from struct net ) or
- * call net_assign_generic() to put the private data on the struct
- * net (most preferably this should be done in the ->init callback
- * of the ops registered);
+ * 2. set pernet_operations->size to have the code allocate and free
+ * a private structure pointed to from struct net.
* 3. do not change this pointer while the net is alive;
* 4. do not try to have any private reference on the net_generic object.
*
@@ -46,6 +43,4 @@ static inline void *net_generic(struct net *net, int id)
return ptr;
}
-
-extern int net_assign_generic(struct net *net, int id, void *data);
#endif
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index bd8c471..777477c 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -27,6 +27,51 @@ EXPORT_SYMBOL(init_net);
#define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */
+static void net_generic_release(struct rcu_head *rcu)
+{
+ struct net_generic *ng;
+
+ ng = container_of(rcu, struct net_generic, rcu);
+ kfree(ng);
+}
+
+static int net_assign_generic(struct net *net, int id, void *data)
+{
+ struct net_generic *ng, *old_ng;
+
+ BUG_ON(!mutex_is_locked(&net_mutex));
+ BUG_ON(id == 0);
+
+ ng = old_ng = net->gen;
+ if (old_ng->len >= id)
+ goto assign;
+
+ ng = kzalloc(sizeof(struct net_generic) +
+ id * sizeof(void *), GFP_KERNEL);
+ if (ng == NULL)
+ return -ENOMEM;
+
+ /*
+ * Some synchronisation notes:
+ *
+ * The net_generic explores the net->gen array inside rcu
+ * read section. Besides once set the net->gen->ptr[x]
+ * pointer never changes (see rules in netns/generic.h).
+ *
+ * That said, we simply duplicate this array and schedule
+ * the old copy for kfree after a grace period.
+ */
+
+ ng->len = id;
+ memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
+
+ rcu_assign_pointer(net->gen, ng);
+ call_rcu(&old_ng->rcu, net_generic_release);
+assign:
+ ng->ptr[id - 1] = data;
+ return 0;
+}
+
static int ops_init(const struct pernet_operations *ops, struct net *net)
{
int err;
@@ -526,49 +571,3 @@ void unregister_pernet_device(struct pernet_operations *ops)
mutex_unlock(&net_mutex);
}
EXPORT_SYMBOL_GPL(unregister_pernet_device);
-
-static void net_generic_release(struct rcu_head *rcu)
-{
- struct net_generic *ng;
-
- ng = container_of(rcu, struct net_generic, rcu);
- kfree(ng);
-}
-
-int net_assign_generic(struct net *net, int id, void *data)
-{
- struct net_generic *ng, *old_ng;
-
- BUG_ON(!mutex_is_locked(&net_mutex));
- BUG_ON(id == 0);
-
- ng = old_ng = net->gen;
- if (old_ng->len >= id)
- goto assign;
-
- ng = kzalloc(sizeof(struct net_generic) +
- id * sizeof(void *), GFP_KERNEL);
- if (ng == NULL)
- return -ENOMEM;
-
- /*
- * Some synchronisation notes:
- *
- * The net_generic explores the net->gen array inside rcu
- * read section. Besides once set the net->gen->ptr[x]
- * pointer never changes (see rules in netns/generic.h).
- *
- * That said, we simply duplicate this array and schedule
- * the old copy for kfree after a grace period.
- */
-
- ng->len = id;
- memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
-
- rcu_assign_pointer(net->gen, ng);
- call_rcu(&old_ng->rcu, net_generic_release);
-assign:
- ng->ptr[id - 1] = data;
- return 0;
-}
-EXPORT_SYMBOL_GPL(net_assign_generic);
^ permalink raw reply related
* [patch] sctp: cleanup: remove unneeded null check
From: Dan Carpenter @ 2010-04-23 11:59 UTC (permalink / raw)
To: Vlad Yasevich
Cc: Sridhar Samudrala, David S. Miller, Wei Yongjun, Chris Dischino,
linux-sctp, netdev, kernel-janitors
"chunk" can never be null here. We dereferenced it earlier in the
function and also at the start of the function we passed it to
sctp_pack_cookie() which dereferences it.
This code has been around since the dawn of git history so if "chunk"
were ever null someone would have complained about it.
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 17cb400..52352fc 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -470,8 +470,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
*
* [INIT ACK back to where the INIT came from.]
*/
- if (chunk)
- retval->transport = chunk->transport;
+ retval->transport = chunk->transport;
nomem_chunk:
kfree(cookie);
^ permalink raw reply related
* nfs41: potential null deref in xprt_reserve_xprt()?
From: Dan Carpenter @ 2010-04-23 12:00 UTC (permalink / raw)
To: iyer-HgOvQuBEEgTQT0dZR+AlfA
Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
I'm going through some Smatch results and had a question.
Until commit 343952fa5a: "nfs41: Get the rpc_xprt * from the rpc_rqst
instead of the rpc_clnt." we assumed that "task->tk_rqstp" can be NULL.
But that patch dereferences it unconditionally.
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 0eea2bf..c144611 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -195,8 +195,8 @@ EXPORT_SYMBOL_GPL(xprt_load_transport);
*/
int xprt_reserve_xprt(struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
^^^^^^^^^^^^^
Can "req" be null here? The patch is a year old, so presumably it
isn't null very often.
If you would like, I can remove the checks for null from the rest of the
function.
regards,
dan carpenter
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/7] Topcliff GbE: Add The Main code [3/3]
From: Masayuki Ohtake @ 2010-04-23 11:56 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 18536 bytes --]
^ permalink raw reply
* [PATCH 1/7] Topcliff GbE: Add The Main code [1/3]
From: Masayuki Ohtake @ 2010-04-23 11:56 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 39156 bytes --]
^ permalink raw reply
* [PATCH 1/7] Topcliff GbE: Add The Main code [2/3]
From: Masayuki Ohtake @ 2010-04-23 11:56 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 39085 bytes --]
^ permalink raw reply
* [PATCH 3/7] Topcliff GbE: Add The Ethtool code [2/2]
From: Masayuki Ohtake @ 2010-04-23 12:00 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 7634 bytes --]
^ permalink raw reply
* [PATCH 2/7] Topcliff GbE: Add The Parameter check code
From: Masayuki Ohtake @ 2010-04-23 11:59 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Andrew, Intel OTC
From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
This patch adds the Parameter check code of GbE driver for Topcliff.
The GbE driver needs all patch[1/7 to 7/7].
Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
drivers/net/pch_gbe/pch_gbe_param.c | 594 ++
+++++++++++++++++++++++++++++++ 1 files changed, 594 insertions(+)
diff -urN linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_param.c
topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_param.c
--- linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_param.c 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_param.c 2010-04-13
18:18:01.000000000 +0900
@@ -0,0 +1,594 @@
+/*!
+ * @file pch_gbe_param.c
+ * @brief Linux PCH Gigabit Ethernet Driver parameter check source file
+ *
+ * @version 1.00
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/13/2010
+ * modified:
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include "pch_debug.h"
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe.h"
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+
+#define PCH_GBE_MAX_NIC 1
+
+#define OPTION_UNSET -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED 1
+
+/* All parameters are treated the same, as an integer array of values.
+ * This macro just reduces the need to repeat the same declaration code
+ * over and over (plus this helps to avoid typo bugs).
+ */
+
+#define PCH_GBE_PARAM_INIT { [0 ... PCH_GBE_MAX_NIC] = OPTION_UNSET }
+#ifdef PCH_GBE_QAC
+#define PCH_GBE_PARAM(X, desc)
+#else
+#define PCH_GBE_PARAM(X, desc) \
+ static int X[PCH_GBE_MAX_NIC+1] = PCH_GBE_PARAM_INIT; \
+ static int num_##X; \
+ module_param_array_named(X, X, int, &num_##X, 0); \
+ MODULE_PARM_DESC(X, desc);
+#endif
+
+/*
+ * Transmit Descriptor Count
+ * Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD
+ * Default Value: PCH_GBE_DEFAULT_TXD
+ */
+PCH_GBE_PARAM(TxDescriptors, "Number of transmit descriptors");
+
+/*
+ * Receive Descriptor Count
+ * Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD
+ * Default Value: PCH_GBE_DEFAULT_RXD
+ */
+PCH_GBE_PARAM(RxDescriptors, "Number of receive descriptors");
+
+/* User Specified Speed Override
+ *
+ * Valid Range: 0, 10, 100, 1000
+ * - 0 - auto-negotiate at all supported speeds
+ * - 10 - only link at 10 Mbps
+ * - 100 - only link at 100 Mbps
+ * - 1000 - only link at 1000 Mbps
+ *
+ * Default Value: 0
+ */
+PCH_GBE_PARAM(Speed, "Speed setting");
+
+/* User Specified Duplex Override
+ *
+ * Valid Range: 0-2
+ * - 0 - auto-negotiate for duplex
+ * - 1 - only link at half duplex
+ * - 2 - only link at full duplex
+ *
+ * Default Value: 0
+ */
+PCH_GBE_PARAM(Duplex, "Duplex setting");
+
+/*
+ * Auto-negotiation Advertisement Override
+ * Valid Range: 0x01-0x0F, 0x20-0x2F
+ *
+ * The AutoNeg value is a bit mask describing which speed and duplex
+ * combinations should be advertised during auto-negotiation.
+ * The supported speed and duplex modes are listed below
+ *
+ * Bit 7 6 5 4 3 2 1 0
+ * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
+ * Duplex Full Full Half Full Half
+ *
+ * Default Value: 0x2F (copper)
+ */
+PCH_GBE_PARAM(AutoNeg, "Advertised auto-negotiation setting");
+#define AUTONEG_ADV_DEFAULT 0x2F
+
+/*
+ * User Specified Flow Control Override
+ * Valid Range: 0-3
+ * - 0 - No Flow Control
+ * - 1 - Rx only, respond to PAUSE frames but do not generate them
+ * - 2 - Tx only, generate PAUSE frames but ignore them on receive
+ * - 3 - Full Flow Control Support
+ * Default Value: Read flow control settings from the EEPROM
+ */
+PCH_GBE_PARAM(FlowControl, "Flow Control setting");
+
+/*
+ * XsumRX - Receive Checksum Offload Enable/Disable
+ * Valid Range: 0, 1
+ * - 0 - disables all checksum offload
+ * - 1 - enables receive IP/TCP/UDP checksum offload
+ * Default Value: PCH_GBE_DEFAULT_RX_CSUM
+ */
+PCH_GBE_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
+
+/*
+ * XsumTX - Transmit Checksum Offload Enable/Disable
+ * Valid Range: 0, 1
+ * - 0 - disables all checksum offload
+ * - 1 - enables transmit IP/TCP/UDP checksum offload
+ * Default Value: PCH_GBE_DEFAULT_TX_CSUM
+ */
+PCH_GBE_PARAM(XsumTX, "Disable or enable Transmit Checksum offload");
+
+struct pch_gbe_option {
+ enum { enable_option, range_option, list_option } type;
+ signed char *name;
+ signed char *err;
+ int def;
+ union {
+ struct { /* range_option info */
+ int min;
+ int max;
+ } r;
+ struct { /* list_option info */
+ int nr;
+ struct pch_gbe_opt_list { int i; signed char *str; } *p;
+ } l;
+ } arg;
+};
+
+/* ------------------------------------------------------------------------
----
+ Function prototype
+---------------------------------------------------------------------------
- */
+static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter);
+static int pch_gbe_validate_option(int *value,
+ struct pch_gbe_option *opt,
+ struct pch_gbe_adapter *adapter);
+
+/* ------------------------------------------------------------------------
----
+ Function
+---------------------------------------------------------------------------
- */
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn static int pch_gbe_validate_option(int *value,
+ * struct pch_gbe_option *opt,
+ * struct pch_gbe_adapter
*adapter)
+ * @brief Validate option
+ * @param value [IN] value
+ * @param opt [IN] option
+ * @param adapter [IN] Board private structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ */
+static int
+pch_gbe_validate_option(int *value, struct pch_gbe_option *opt,
+ struct pch_gbe_adapter *adapter)
+{
+ if (*value == OPTION_UNSET) {
+ *value = opt->def;
+ return 0;
+ }
+
+ switch (opt->type) {
+ case enable_option:
+ switch (*value) {
+ case OPTION_ENABLED:
+ DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name);
+ return 0;
+ case OPTION_DISABLED:
+ DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name);
+ return 0;
+ }
+ break;
+ case range_option:
+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+ DPRINTK(PROBE, INFO,
+ "%s set to %i\n", opt->name, *value);
+ return 0;
+ }
+ break;
+ case list_option: {
+ int i;
+ struct pch_gbe_opt_list *ent;
+
+ for (i = 0; i < opt->arg.l.nr; i++) {
+ ent = &opt->arg.l.p[i];
+ if (*value == ent->i) {
+ if (ent->str[0] != '\0')
+ DPRINTK(PROBE, INFO, "%s\n", ent->str);
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n",
+ opt->name, *value, opt->err);
+ *value = opt->def;
+ return -1;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
+ * @brief Range Checking for Command Line Parameters
+ * @param adapter [IN] Board private structure
+ * @return None
+ * @remarks
+ * This routine checks all command line parameters for valid user
+ * input. If an invalid value is given, or if no user specified
+ * value exists, a default value is used. The final value is stored
+ * in a variable in the adapter structure.
+ */
+void
+pch_gbe_check_options(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int bd = adapter->bd_number;
+
+ PCH_DEBUG("pch_gbe_check_options\n");
+
+ if (bd >= PCH_GBE_MAX_NIC) {
+ DPRINTK(PROBE, NOTICE,
+ "Warning: no configuration for board #%i\n", bd);
+ DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
+ }
+
+ { /* Transmit Descriptor Count */
+ struct pch_gbe_option opt = {
+ .type = range_option,
+ .name = "Transmit Descriptors",
+ .err = "using default of "
+ __MODULE_STRING(PCH_GBE_DEFAULT_TXD),
+ .def = PCH_GBE_DEFAULT_TXD,
+ .arg = { .r = { .min = PCH_GBE_MIN_TXD } },
+ .arg = { .r = { .max = PCH_GBE_MAX_TXD } }
+ };
+ struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
+ if (num_TxDescriptors > bd) {
+ tx_ring->count = TxDescriptors[bd];
+ pch_gbe_validate_option(&tx_ring->count, &opt, adapter);
+ PCH_GBE_ROUNDUP(tx_ring->count,
+ PCH_GBE_TX_DESC_MULTIPLE);
+ } else {
+ tx_ring->count = opt.def;
+ }
+ }
+ { /* Receive Descriptor Count */
+ struct pch_gbe_option opt = {
+ .type = range_option,
+ .name = "Receive Descriptors",
+ .err = "using default of "
+ __MODULE_STRING(PCH_GBE_DEFAULT_RXD),
+ .def = PCH_GBE_DEFAULT_RXD,
+ .arg = { .r = { .min = PCH_GBE_MIN_RXD } },
+ .arg = { .r = { .max = PCH_GBE_MAX_RXD } }
+ };
+ struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
+ if (num_RxDescriptors > bd) {
+ rx_ring->count = RxDescriptors[bd];
+ pch_gbe_validate_option(&rx_ring->count, &opt, adapter);
+ PCH_GBE_ROUNDUP(rx_ring->count,
+ PCH_GBE_RX_DESC_MULTIPLE);
+ } else {
+ rx_ring->count = opt.def;
+ }
+ }
+ { /* Checksum Offload Enable/Disable */
+ struct pch_gbe_option opt = {
+ .type = enable_option,
+ .name = "Checksum Offload",
+ .err = "defaulting to Enabled",
+ .def = PCH_GBE_DEFAULT_RX_CSUM
+ };
+
+ if (num_XsumRX > bd) {
+ adapter->rx_csum = XsumRX[bd];
+ pch_gbe_validate_option((int *)(&adapter->rx_csum),
+ &opt, adapter);
+ } else {
+ adapter->rx_csum = opt.def;
+ }
+ }
+ { /* Checksum Offload Enable/Disable */
+ struct pch_gbe_option opt = {
+ .type = enable_option,
+ .name = "Checksum Offload",
+ .err = "defaulting to Enabled",
+ .def = PCH_GBE_DEFAULT_TX_CSUM
+ };
+
+ if (num_XsumTX > bd) {
+ adapter->tx_csum = XsumTX[bd];
+ pch_gbe_validate_option((int *)(&adapter->tx_csum),
+ &opt, adapter);
+ } else {
+ adapter->tx_csum = opt.def;
+ }
+ }
+ { /* Flow Control */
+
+ struct pch_gbe_opt_list fc_list[] = {
+ {pch_gbe_fc_none, "Flow Control Disabled"},
+ {pch_gbe_fc_rx_pause, "Flow Control Receive Only"},
+ {pch_gbe_fc_tx_pause, "Flow Control Transmit Only"},
+ {pch_gbe_fc_full, "Flow Control Enabled"} };
+
+ struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Flow Control",
+ .err = "reading default settings from EEPROM",
+ .def = PCH_GBE_FC_DEFAULT,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list),
+ .p = fc_list } }
+ };
+
+ if (num_FlowControl > bd) {
+ hw->mac.fc = FlowControl[bd];
+ pch_gbe_validate_option((int *)(&hw->mac.fc),
+ &opt, adapter);
+ } else {
+ hw->mac.fc = opt.def;
+ }
+ }
+
+ pch_gbe_check_copper_options(adapter);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn static void pch_gbe_check_copper_options(
+ * struct pch_gbe_adapter *adapter)
+ * @brief Range Checking for Link Options, Copper Version
+ * @param adapter [IN] Board private structure
+ * @return None
+ * @remarks
+ * Handles speed and duplex options on copper adapters
+ */
+static void
+pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter)
+{
+ struct pch_gbe_hw *hw = &adapter->hw;
+ int speed, dplx;
+ int bd = adapter->bd_number;
+
+ { /* Speed */
+ struct pch_gbe_opt_list speed_list[] = {
+ {0, "" },
+ {SPEED_10, ""},
+ {SPEED_100, ""},
+ {SPEED_1000, ""} };
+
+ struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Speed",
+ .err = "parameter ignored",
+ .def = 0,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list),
+ .p = speed_list } }
+ };
+
+ if (num_Speed > bd) {
+ speed = Speed[bd];
+ pch_gbe_validate_option(&speed, &opt, adapter);
+ } else {
+ speed = opt.def;
+ }
+ }
+ { /* Duplex */
+ struct pch_gbe_opt_list dplx_list[] = {
+ {0, ""},
+ {PHY_HALF_DUPLEX, ""},
+ {PHY_FULL_DUPLEX, ""} };
+
+ struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "Duplex",
+ .err = "parameter ignored",
+ .def = 0,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list),
+ .p = dplx_list } }
+ };
+
+ if (num_Duplex > bd) {
+ dplx = Duplex[bd];
+ pch_gbe_validate_option(&dplx, &opt, adapter);
+ } else {
+ dplx = opt.def;
+ }
+ }
+
+ { /* Autoneg */
+ struct pch_gbe_opt_list an_list[] =
+ #define AA "AutoNeg advertising "
+ {{ 0x01, AA "10/HD" },
+ { 0x02, AA "10/FD" },
+ { 0x03, AA "10/FD, 10/HD" },
+ { 0x04, AA "100/HD" },
+ { 0x05, AA "100/HD, 10/HD" },
+ { 0x06, AA "100/HD, 10/FD" },
+ { 0x07, AA "100/HD, 10/FD, 10/HD" },
+ { 0x08, AA "100/FD" },
+ { 0x09, AA "100/FD, 10/HD" },
+ { 0x0a, AA "100/FD, 10/FD" },
+ { 0x0b, AA "100/FD, 10/FD, 10/HD" },
+ { 0x0c, AA "100/FD, 100/HD" },
+ { 0x0d, AA "100/FD, 100/HD, 10/HD" },
+ { 0x0e, AA "100/FD, 100/HD, 10/FD" },
+ { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x20, AA "1000/FD" },
+ { 0x21, AA "1000/FD, 10/HD" },
+ { 0x22, AA "1000/FD, 10/FD" },
+ { 0x23, AA "1000/FD, 10/FD, 10/HD" },
+ { 0x24, AA "1000/FD, 100/HD" },
+ { 0x25, AA "1000/FD, 100/HD, 10/HD" },
+ { 0x26, AA "1000/FD, 100/HD, 10/FD" },
+ { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
+ { 0x28, AA "1000/FD, 100/FD" },
+ { 0x29, AA "1000/FD, 100/FD, 10/HD" },
+ { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
+ { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
+ { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
+ { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
+ { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
+ { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" } };
+
+ struct pch_gbe_option opt = {
+ .type = list_option,
+ .name = "AutoNeg",
+ .err = "parameter ignored",
+ .def = AUTONEG_ADV_DEFAULT,
+ .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list),
+ .p = an_list} }
+ };
+
+ if (num_AutoNeg > bd) {
+ if (speed != 0 || dplx != 0) {
+ DPRINTK(PROBE, INFO,
+ "AutoNeg specified along with Speed or Duplex, "
+ "parameter ignored\n");
+ hw->phy.autoneg_advertised = opt.def;
+ } else {
+ hw->phy.autoneg_advertised = AutoNeg[bd];
+ pch_gbe_validate_option(
+ (int *)(&hw->phy.autoneg_advertised),
+ &opt, adapter);
+ }
+ } else {
+ hw->phy.autoneg_advertised = opt.def;
+ }
+ }
+
+ switch (speed + dplx) {
+ case 0:
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ if ((num_Speed > bd) && (speed != 0 || dplx != 0))
+ DPRINTK(PROBE, INFO,
+ "Speed and duplex autonegotiation enabled\n");
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_HALF_DUPLEX:
+ DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n");
+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+ "Half Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+ PHY_ADVERTISE_100_HALF;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_FULL_DUPLEX:
+ DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n");
+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+ "Full Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |
+ PHY_ADVERTISE_100_FULL |
+ PHY_ADVERTISE_1000_FULL;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case PHY_SPEED_10:
+ DPRINTK(PROBE, INFO, "10 Mbps Speed specified "
+ "without Duplex\n");
+ DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+ PHY_ADVERTISE_10_FULL;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_SPEED_10 + PHY_HALF_DUPLEX:
+ DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Half Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_SPEED_10 + PHY_FULL_DUPLEX:
+ DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Full Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_10;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case PHY_SPEED_100:
+ DPRINTK(PROBE, INFO, "100 Mbps Speed specified "
+ "without Duplex\n");
+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+ "100 Mbps only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |
+ PHY_ADVERTISE_100_FULL;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_SPEED_100 + PHY_HALF_DUPLEX:
+ DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Half Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_HALF;
+ break;
+ case PHY_SPEED_100 + PHY_FULL_DUPLEX:
+ DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Full Duplex\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+ hw->phy.autoneg_advertised = 0;
+ hw->mac.link_speed = SPEED_100;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ case PHY_SPEED_1000:
+ DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without "
+ "Duplex\n");
+ goto full_duplex_only;
+ case PHY_SPEED_1000 + PHY_HALF_DUPLEX:
+ DPRINTK(PROBE, INFO,
+ "Half Duplex is not supported at 1000 Mbps\n");
+ /* fall through */
+ case PHY_SPEED_1000 + PHY_FULL_DUPLEX:
+full_duplex_only:
+ DPRINTK(PROBE, INFO,
+ "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+ hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+ hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;
+ hw->mac.link_speed = SPEED_1000;
+ hw->mac.link_duplex = DUPLEX_FULL;
+ break;
+ default:
+ BUG();
+ }
+}
+
^ permalink raw reply
* [PATCH 4/7] Topcliff GbE: Add The Hardware layer I/F code
From: Masayuki Ohtake @ 2010-04-23 12:00 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
This patch adds the Hardware layer I/F code of GbE driver for Topcliff.
The GbE driver needs all patch[1/7 to 7/7].
Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
drivers/net/pch_gbe/pch_gbe_api.c | 648 ++
drivers/net/pch_gbe/pch_gbe_api.h | 251
drivers/net/pch_gbe/pch_gbe_plat.c | 175
+++++++++++++++++++++++++++++++ 3 files changed, 1074 insertions(+)
diff -urN linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.c
topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.c
--- linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.c 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.c 2010-04-13
19:23:50.000000000 +0900
@@ -0,0 +1,648 @@
+/*!
+ * @file pch_gbe_api.c
+ * @brief Linux PCH Gigabit Ethernet Driver HAL API source file
+ *
+ * @version 1.00
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/13/2010
+ * modified:
+ *
+ */
+
+#include "pch_debug.h"
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_mac.h"
+#include "pch_gbe_api.h"
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_set_mac_type(struct pch_gbe_hw *hw)
+ * @brief Sets MAC type
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks This function sets the mac type of the adapter based on the
+ * device ID stored in the hw structure.
+ * MUST BE FIRST FUNCTION CALLED (explicitly or through
+ * pch_gbe_hal_setup_init_funcs()).
+ */
+s32 pch_gbe_hal_set_mac_type(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_mac_info *mac = &hw->mac;
+ s32 ret_val = PCH_GBE_SUCCESS;
+
+ PCH_DEBUG("pch_gbe_hal_set_mac_type\n");
+
+ switch ((u16) hw->device_id) {
+ case PCI_DEVICE_ID_INTEL_IOH1_GBE:
+ mac->type = PCH_GBE_MAC_TYPE_PCH1;
+ break;
+ default:
+ /* Should never have loaded on this device */
+ mac->type = PCH_GBE_MAC_TYPE_UNDEFINED;
+ ret_val = -PCH_GBE_ERR_MAC_INIT;
+ break;
+ }
+ PCH_DEBUG("mac->type:0x%x ret_val:0x%x\n", mac->type, ret_val);
+ return ret_val;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
+ * @brief Initializes function pointers
+ * @param hw [INOUT] pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks This function must be called by a driver in order to use the
rest
+ * of the 'shared' code files. Called by drivers only.
+ */
+s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
+{
+ s32 ret_val;
+
+ PCH_DEBUG("pch_gbe_hal_setup_init_funcs\n");
+
+ /* Can't do much good without knowing the MAC type.
+ */
+ ret_val = pch_gbe_hal_set_mac_type(hw);
+ if (ret_val) {
+ PCH_LOG(KERN_ERR,
+ "ERROR: MAC type could not be set properly.\n");
+ goto out;
+ }
+
+ if (!hw->hw_addr) {
+ PCH_LOG(KERN_ERR, "ERROR: Registers not mapped\n");
+ ret_val = -PCH_GBE_ERR_CONFIG;
+ goto out;
+ }
+
+ /* Set up the init function pointers. These are functions within the
+ * adapter family file that sets up function pointers for the rest of
+ * the functions in that family.
+ */
+ switch (hw->mac.type) {
+ case PCH_GBE_MAC_TYPE_PCH1:
+ case PCH_GBE_MAC_TYPE_PCH2:
+ pch_gbe_plat_init_function_pointers(hw);
+ break;
+ default:
+ PCH_LOG(KERN_ERR, "Hardware not supported\n");
+ ret_val = -PCH_GBE_ERR_CONFIG;
+ break;
+ }
+out:
+ PCH_DEBUG("ret_val:0x%x\n", ret_val);
+ return ret_val;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
+ * @brief Obtain bus information for adapter
+ * @param hw [INOUT] pointer to the HW structure
+ * @return None
+ * @remarks This will obtain information about the HW bus for which the
+ * adaper is attached and stores it in the hw structure. This is a
+ * function pointer entry point called by drivers.
+ */
+void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_get_bus_info\n");
+
+ if (hw->func.get_bus_info != NULL)
+ hw->func.get_bus_info(hw);
+ else
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_mc_addr_list_update(struct pch_gbe_hw *hw,
+ * u8 *mc_addr_list, u32 mc_addr_count,
+ * u32 mar_used_count, u32 mar_count)
+ * @brief Update Multicast addresses
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param mc_addr_list [IN]Array of multicast addresses to program
+ * @param mc_addr_count [IN]Number of multicast addresses to program
+ * @param mar_used_count [IN]The first MAC Address register free to
program
+ * @param mar_count [IN]Total number of supported MAC Address Registers
+ * @return None
+ * @remarks
+ * Updates the MAC Address Registers and Multicast Table Array.
+ * The caller must have a packed mc_addr_list of multicast addresses.
+ * The parameter mar_count will usually be hw->mac.mar_entry_count
+ * unless there are workarounds that change this. Currently no func
pointer
+ * exists and all implementations are handled in the generic version of
this
+ * function.
+ */
+void
+pch_gbe_hal_mc_addr_list_update(struct pch_gbe_hw *hw,
+ u8 *mc_addr_list,
+ u32 mc_addr_count,
+ u32 mar_used_count, u32 mar_count)
+{
+ PCH_DEBUG("pch_gbe_hal_mc_addr_list_update\n");
+
+ if (hw->func.mc_addr_list_update != NULL) {
+ hw->func.mc_addr_list_update(hw,
+ mc_addr_list,
+ mc_addr_count,
+ mar_used_count, mar_count);
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_force_mac_fc(struct pch_gbe_hw *hw)
+ * @brief Force MAC flow control
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Force the MAC's flow control settings. Currently no func pointer exists
+ * and all implementations are handled in the generic version of this
+ * function.
+ */
+s32 pch_gbe_hal_force_mac_fc(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_force_mac_fc\n");
+
+ return pch_gbe_mac_force_mac_fc(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_reset_hw(struct pch_gbe_hw *hw)
+ * @brief Reset hardware
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This resets the hardware into a known state. This is a function pointer
+ * entry point called by drivers.
+ */
+s32 pch_gbe_hal_reset_hw(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_reset_hw\n");
+
+ if (hw->func.reset_hw != NULL) {
+ hw->func.reset_hw(hw);
+ return PCH_GBE_SUCCESS;
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
+ * @brief Initialize hardware
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This inits the hardware readying it for operation. This is a function
+ * pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_init_hw\n");
+
+ if (hw->func.init_hw != NULL) {
+ return hw->func.init_hw(hw);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_link(struct pch_gbe_hw *hw)
+ * @brief Configures link and flow control
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This configures link and flow control settings for the adapter. This
+ * is a function pointer entry point called by drivers. While modules can
+ * also call this, they probably call their own version of this function.
+ */
+s32 pch_gbe_hal_setup_link(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_setup_link\n");
+
+ if (hw->func.setup_link != NULL) {
+ return hw->func.setup_link(hw);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_led(struct pch_gbe_hw *hw)
+ * @brief Configures SW controllable LED
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This prepares the SW controllable LED for use and saves the current
state
+ * of the LED so it can be later restored. This is a function pointer
entry
+ * point called by drivers.
+ */
+s32 pch_gbe_hal_setup_led(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_setup_led\n");
+
+ if (hw->func.setup_led != NULL)
+ return hw->func.setup_led(hw);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_cleanup_led(struct pch_gbe_hw *hw)
+ * @brief Restores SW controllable LED
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This restores the SW controllable LED to the value saved off by
+ * pch_gbe_hal_setup_led.
+ * This is a function pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_cleanup_led(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_cleanup_led\n");
+
+ if (hw->func.cleanup_led != NULL)
+ return hw->func.cleanup_led(hw);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_led_on(struct pch_gbe_hw *hw)
+ * @brief Turn on SW controllable LED
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Turns the SW defined LED on. This is a function pointer entry point
+ * called by drivers.
+ */
+s32 pch_gbe_hal_led_on(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_led_on\n");
+
+ if (hw->func.led_on != NULL)
+ return hw->func.led_on(hw);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_led_off(struct pch_gbe_hw *hw)
+ * @brief Turn off SW controllable LED
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Turns the SW defined LED off. This is a function pointer entry point
+ * called by drivers.
+ */
+s32 pch_gbe_hal_led_off(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_led_off\n");
+
+ if (hw->func.led_off != NULL)
+ return hw->func.led_off(hw);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_mar_set(struct pch_gbe_hw *hw, u8 *addr, u32
index)
+ * @brief Sets a MAC address register
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param addr [IN] Address to set the RAR to
+ * @param index [IN] The RAR to set
+ * @return None
+ * @remarks
+ * Sets a MAC Address Register (RAR) to the specified address.
+ * Currently no func pointer exists and all implementations are
+ * handled in the generic version of this function.
+ */
+void pch_gbe_hal_mar_set(struct pch_gbe_hw *hw, u8 *addr, u32 index)
+{
+ PCH_DEBUG("pch_gbe_hal_mar_set\n");
+
+ pch_gbe_mac_mar_set(hw, addr, index);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw,
+ * u32 offset, u16 *data)
+ * @brief Reads PHY register
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param offset [IN] The register to read
+ * @param data [IN] The buffer to store the 16-bit read.
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Reads the PHY register and returns the value in data.
+ * This is a function pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data)
+{
+ PCH_DEBUG("pch_gbe_hal_read_phy_reg\n");
+
+ if (hw->func.read_phy_reg != NULL)
+ return hw->func.read_phy_reg(hw, offset, data);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw,
+ * u32 offset, u16 data)
+ * @brief Writes PHY register
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param offset [IN] The register to write
+ * @param data [IN] The value to write.
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Writes the PHY register at offset with the value in data.
+ * This is a function pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data)
+{
+ PCH_DEBUG("pch_gbe_hal_write_phy_reg\n");
+
+ if (hw->func.write_phy_reg != NULL)
+ return hw->func.write_phy_reg(hw, offset, data);
+ else
+ return PCH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
+ * @brief Hard PHY reset
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return None
+ * @remarks
+ * Performs a hard PHY reset. This is a function pointer entry point
called
+ * by drivers.
+ */
+void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_phy_hw_reset\n");
+
+ if (hw->func.reset_phy != NULL)
+ hw->func.reset_phy(hw);
+ else
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
+ * @brief Soft PHY reset
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return None
+ * @remarks
+ * Performs a soft PHY reset on those that apply. This is a function
pointer
+ * entry point called by drivers.
+ */
+void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_phy_sw_reset\n");
+
+ if (hw->func.sw_reset_phy != NULL)
+ hw->func.sw_reset_phy(hw);
+ else
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
+ * @brief Reads MAC address
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Reads the MAC address out of the adapter and stores it in the HW
structure.
+ * Currently no func pointer exists and all implementations are handled in
the
+ * generic version of this function.
+ */
+s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_read_mac_addr\n");
+
+ if (hw->func.read_mac_addr != NULL) {
+ return hw->func.read_mac_addr(hw);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+#ifdef CONFIG_PCH_PHUB
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_validate_nvm_checksum(struct pch_gbe_hw *hw)
+ * @brief Verifies NVM (EEPROM) checksum
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Validates the NVM checksum is correct. This is a function pointer entry
+ * point called by drivers.
+ */
+s32 pch_gbe_hal_validate_nvm_checksum(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_validate_nvm_checksum\n");
+
+ if (hw->func.validate_nvm != NULL) {
+ return hw->func.validate_nvm(hw);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_nvm(struct pch_gbe_hw *hw,
+ * u32 offset, u8 *data)
+ * @brief Reads NVM (EEPROM)
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param offset [IN] The word offset to read
+ * @param data [IN] Pointer to the properly sized buffer for the data.
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
+ * pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_read_nvm(struct pch_gbe_hw *hw, u32 offset, u8 *data)
+{
+ PCH_DEBUG("pch_gbe_hal_read_nvm\n");
+
+ if (hw->func.read_nvm != NULL) {
+ return hw->func.read_nvm(hw, offset, data);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return -PCH_GBE_ERR_CONFIG;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_write_nvm(struct pch_gbe_hw *hw,
+ * u32 offset, u8 *data)
+ * @brief Writes to NVM (EEPROM)
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param offset [IN] The word offset to read
+ * @param data [IN] Pointer to the properly sized buffer for the data.
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
+ * pointer entry point called by drivers.
+ */
+s32 pch_gbe_hal_write_nvm(struct pch_gbe_hw *hw, u32 offset, u8 *data)
+{
+ PCH_DEBUG("pch_gbe_hal_write_nvm\n");
+
+ if (hw->func.write_nvm != NULL)
+ return hw->func.write_nvm(hw, offset, data);
+ else
+ return PCH_GBE_SUCCESS;
+}
+#endif /* CONFIG_PCH_PHUB */
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_set_wol_event(struct pch_gbe_hw *hw, u32
wu_evt)
+ * @brief Set wake-on-lan event
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param wu_evt [IN] Wake up event
+ * @return None
+ */
+void pch_gbe_hal_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt)
+{
+ PCH_DEBUG("pch_gbe_hal_set_wol_event\n");
+
+ pch_gbe_mac_set_wol_event(hw, wu_evt);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
+ * @brief Power up PHY
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return None
+ */
+void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_power_up_phy\n");
+
+ if (hw->func.power_up_phy != NULL)
+ hw->func.power_up_phy(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
+ * @brief Power down PHY
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return None
+ */
+void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_power_down_phy\n");
+
+ if (hw->func.power_down_phy != NULL)
+ hw->func.power_down_phy(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn u16 pch_gbe_hal_ctrl_miim(struct pch_gbe_hw *hw,
+ * u32 addr, u32 dir, u32 reg, u16 data)
+ * @brief Control MII Management IF
+ * @param hw [INOUT] Pointer to the HW structure
+ * @param addr [IN] Address of PHY
+ * @param dir [IN] Operetion. (Write or Read)
+ * @param reg [IN] Access register of PHY
+ * @param data [IN] Write data
+ * @return None
+ */
+u16
+pch_gbe_hal_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+ u16 data)
+{
+#ifdef DEBUG_TEST
+ PCH_DEBUG("pch_gbe_hal_ctrl_miim\n");
+#endif
+ if (hw->func.ctrl_miim != NULL) {
+ return hw->func.ctrl_miim(hw, addr, dir, reg, data);
+ } else {
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+ return PCH_GBE_SUCCESS;
+ }
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_set_pause_packet(struct pch_gbe_hw *hw)
+ * @brief Set pause packet
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return None
+ */
+void pch_gbe_hal_set_pause_packet(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_hal_set_pause_packet\n");
+
+ if (hw->func.pause_packet != NULL)
+ hw->func.pause_packet(hw);
+ else
+ PCH_LOG(KERN_ERR, "Error: configuration\n");
+}
diff -urN linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.h
topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.h
--- linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.h 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_api.h 2010-04-13
19:25:22.000000000 +0900
@@ -0,0 +1,251 @@
+/*!
+ * @file pch_gbe_api.h
+ * @brief Linux PCH Gigabit Ethernet Driver HAL API header file
+ *
+ * @version 1.00
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/13/2010
+ * modified:
+ *
+ */
+
+#ifndef _PCH_GBE_API_H_
+#define _PCH_GBE_API_H_
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_set_mac_type(struct pch_gbe_hw *hw)
+ * @brief Sets MAC type
+ */
+s32 pch_gbe_hal_set_mac_type(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
+ * @brief Initializes function pointers
+ */
+s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
+ * @brief Obtain bus information for adapter
+ */
+void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_mc_addr_list_update(struct pch_gbe_hw *hw,
+ * u8 *mc_addr_list, u32 mc_addr_count,
+ * u32 mar_used_count, u32 mar_count)
+ * @brief Update Multicast addresses
+ */
+void pch_gbe_hal_mc_addr_list_update(struct pch_gbe_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 mar_used_count, u32 mar_count);
+
+/*
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_force_mac_fc(struct pch_gbe_hw *hw)
+ * @brief Force MAC flow control
+ */
+s32 pch_gbe_hal_force_mac_fc(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_reset_hw(struct pch_gbe_hw *hw)
+ * @brief Reset hardware
+ */
+s32 pch_gbe_hal_reset_hw(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
+ * @brief Initialize hardware
+ */
+s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_link(struct pch_gbe_hw *hw)
+ * @brief Configures link and flow control
+ */
+s32 pch_gbe_hal_setup_link(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_setup_led(struct pch_gbe_hw *hw)
+ * @brief Configures SW controllable LED
+ */
+s32 pch_gbe_hal_setup_led(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_cleanup_led(struct pch_gbe_hw *hw)
+ * @brief Restores SW controllable LED
+ */
+s32 pch_gbe_hal_cleanup_led(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_led_on(struct pch_gbe_hw *hw)
+ * @brief Turn on SW controllable LED
+ */
+s32 pch_gbe_hal_led_on(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_led_off(struct pch_gbe_hw *hw)
+ * @brief Turn off SW controllable LED
+ */
+s32 pch_gbe_hal_led_off(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_mar_set(struct pch_gbe_hw *hw, u8 *addr, u32
index)
+ * @brief Sets a MAC address register
+ */
+void pch_gbe_hal_mar_set(struct pch_gbe_hw *hw, u8 *addr, u32 index);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw,
+ * u32 offset, u16 *data)
+ * @brief Reads PHY register
+ */
+s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw,
+ * u32 offset, u16 data)
+ * @brief Writes PHY register
+ */
+s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
+ * @brief Hard PHY reset
+ */
+void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
+ * @brief Soft PHY reset
+ */
+void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
+ * @brief Reads MAC address
+ */
+s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw);
+
+#ifdef CONFIG_PCH_PHUB
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_validate_nvm_checksum(struct pch_gbe_hw *hw)
+ * @brief Verifies NVM (EEPROM) checksum
+ */
+s32 pch_gbe_hal_validate_nvm_checksum(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_read_nvm(struct pch_gbe_hw *hw,
+ * u32 offset, u8 *data)
+ * @brief Reads NVM (EEPROM)
+ */
+s32 pch_gbe_hal_read_nvm(struct pch_gbe_hw *hw, u32 offset, u8 *data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn s32 pch_gbe_hal_write_nvm(struct pch_gbe_hw *hw,
+ * u32 offset, u8 *data)
+ * @brief Writes to NVM (EEPROM)
+ */
+s32 pch_gbe_hal_write_nvm(struct pch_gbe_hw *hw, u32 offset, u8 *data);
+#endif /* CONFIG_PCH_PHUB */
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_set_wol_event(struct pch_gbe_hw *hw, u32
wu_evt)
+ * @brief Set wake-on-lan event
+ */
+void pch_gbe_hal_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
+ * @brief Power up PHY
+ */
+void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
+ * @brief Power down PHY
+ */
+void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn u16 pch_gbe_hal_ctrl_miim(struct pch_gbe_hw *hw,
+ * u32 addr, u32 dir, u32 reg, u16 data)
+ * @brief Control MII Management IF
+ */
+u16 pch_gbe_hal_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32
reg,
+ u16 data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn void pch_gbe_hal_set_pause_packet(struct pch_gbe_hw *hw)
+ * @brief Set pause packet
+ */
+void pch_gbe_hal_set_pause_packet(struct pch_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @def PCH_GBE_HAL_MIIM_READ
+ * @brief Read operation is done through MII Management IF
+ */
+#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000)
+
+/*!
+ * @ingroup HAL API Layer
+ * @def PCH_GBE_HAL_MIIM_WRITE
+ * @brief Write operation is done through MII Management IF
+ */
+#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000)
+
+/* pch_gbe_plat.c */
+/*!
+ * @ingroup HAL internal functions
+ * @fn void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
+ * @brief Init func ptrs.
+ */
+void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw);
+
+#endif
diff -urN linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_plat.c
topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_plat.c
--- linux-2.6.33.1/drivers/net/pch_gbe/pch_gbe_plat.c 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/pch_gbe/pch_gbe_plat.c 2010-04-13
19:25:07.000000000 +0900
@@ -0,0 +1,175 @@
+/*!
+ * @file pch_gbe_plat.c
+ * @brief Linux PCH Gigabit Ethernet Driver HAL internal function
(platform) source file
+ *
+ * @version 1.00
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *
+ * created:
+ * OKI SEMICONDUCTOR 04/13/2010
+ * modified:
+ *
+ */
+
+#include "pch_debug.h"
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_mac.h"
+#include "pch_gbe_nvm.h"
+#include "pch_gbe_phy.h"
+#include "pch_gbe_api.h"
+
+
+static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw);
+static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw);
+
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
+ * @brief Init func ptrs.
+ * @param hw [OUT] Pointer to the HW structure
+ * @return None
+ * @remarks
+ * The only function explicitly called by the api module to initialize
+ * all function pointers and parameters.
+ */
+void
+pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_mac_info *mac = &hw->mac;
+ struct pch_gbe_phy_info *phy = &hw->phy;
+ struct pch_gbe_nvm_info *nvm = &hw->nvm;
+ struct pch_gbe_functions *func = &hw->func;
+
+ PCH_DEBUG("pch_gbe_plat_init_function_pointers\n");
+
+ /* Set MAC address registers entry count */
+ mac->mar_entry_count = PCH_GBE_MAR_ENTRIES;
+ /* Set PHY parameter */
+ phy->reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US;
+ /* Set NVM parameter */
+ nvm->word_size = PCH_GBE_NVM_WORD_SIZE;
+
+ /* Set function pointers */
+ func->get_bus_info = pch_gbe_plat_get_bus_info;
+ func->reset_hw = pch_gbe_mac_reset_hw;
+ func->init_hw = pch_gbe_plat_init_hw;
+ func->setup_link = pch_gbe_mac_setup_link;
+ func->setup_physical_interface = pch_gbe_phy_setup_link_fpga;
+ func->mc_addr_list_update = pch_gbe_mac_mc_addr_list_update;
+ func->setup_led = pch_gbe_phy_led_setup;
+ func->cleanup_led = pch_gbe_phy_led_cleanup;
+ func->led_on = pch_gbe_phy_led_on;
+ func->led_off = pch_gbe_phy_led_off;
+ func->read_phy_reg = pch_gbe_phy_read_reg_miic;
+ func->write_phy_reg = pch_gbe_phy_write_reg_miic;
+ func->reset_phy = pch_gbe_phy_hw_reset;
+ func->sw_reset_phy = pch_gbe_phy_sw_reset;
+ func->power_up_phy = pch_gbe_phy_power_up;
+ func->power_down_phy = pch_gbe_phy_power_down;
+#ifdef CONFIG_PCH_PHUB
+ func->read_nvm = pch_gbe_nvm_read_mem;
+ func->write_nvm = pch_gbe_nvm_write_mem;
+ func->validate_nvm = pch_gbe_nvm_validate_checksum;
+ func->read_mac_addr = pch_gbe_nvm_read_mac_addr;
+#else
+ func->read_mac_addr = pch_gbe_mac_read_mac_addr;
+#endif
+ func->ctrl_miim = pch_gbe_mac_ctrl_miim;
+ func->pause_packet = pch_gbe_mac_set_pause_packet;
+
+#ifdef DEBUG_TEST
+ PCH_DEBUG("[MAC]mar_entry_count:%d /[PHY] reset_delay_us:%d\n",
+ mac->mar_entry_count, phy->reset_delay_us);
+ PCH_DEBUG("[NVM] word_size:0x%08x\n", nvm->word_size);
+#endif
+}
+
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)
+ * @brief Obtain bus information for adapter
+ * @param hw [OUT] Pointer to the HW structure
+ * @return None
+ * @remarks
+ * This will obtain information about the HW bus for which the
+ * adaper is attached and stores it in the hw structure. This is a
function
+ * pointer entry point called by the api module.
+ */
+static void
+pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)
+{
+ PCH_DEBUG("pch_gbe_plat_get_bus_info\n");
+
+ hw->bus.type = pch_gbe_bus_type_pci_express;
+ hw->bus.speed = pch_gbe_bus_speed_2500;
+ hw->bus.width = pch_gbe_bus_width_pcie_x1;
+
+#ifdef DEBUG_TEST
+ PCH_DEBUG("[BUS] type:0x%08x speed:0x%08x width:0x%08x\n",
+ hw->bus.type, hw->bus.speed, hw->bus.width);
+#endif
+}
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
+ * @brief Initialize hardware
+ * @param hw [INOUT] Pointer to the HW structure
+ * @return PCH_GBE_SUCCESS: Successfully
+ * @return Negative value: Failed
+ * @remarks
+ * This inits the hardware readying it for operation. This is a
+ * function pointer entry point called by the api module.
+ */
+static s32
+pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
+{
+ struct pch_gbe_mac_info *mac = &hw->mac;
+ s32 ret_val;
+
+ PCH_DEBUG("pch_gbe_plat_init_hw\n");
+
+ /* Setup the receive address. */
+ pch_gbe_mac_init_rx_addrs(hw, mac->mar_entry_count);
+
+ ret_val = pch_gbe_phy_get_id(hw);
+ if (ret_val) {
+ PCH_LOG(KERN_ERR, "pch_gbe_phy_get_id error\n");
+ return ret_val;
+ }
+ pch_gbe_phy_init_setting(hw);
+ /* Setup Mac interface option RGMII */
+#ifdef PCH_GBE_MAC_IFOP_RGMII
+ pch_gbe_phy_set_rgmii(hw);
+#endif
+ /* Setup link and flow control */
+ ret_val = pch_gbe_hal_setup_link(hw);
+#ifdef DEBUG_TEST
+ if (ret_val)
+ PCH_LOG(KERN_ERR, "pch_gbe_phy_get_id error\n");
+#endif
+ return ret_val;
+}
+
^ permalink raw reply
* [PATCH 3/7] Topcliff GbE: Add The Ethtool code [1/2]
From: Masayuki Ohtake @ 2010-04-23 12:00 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 39196 bytes --]
^ permalink raw reply
* [PATCH 5/7] Topcliff GbE: Add The Hardware layer codes [2/2]
From: Masayuki Ohtake @ 2010-04-23 12:00 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 9627 bytes --]
^ permalink raw reply
* [PATCH 5/7] Topcliff GbE: Add The Hardware layer codes [1/2]
From: Masayuki Ohtake @ 2010-04-23 12:00 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 39112 bytes --]
^ permalink raw reply
* [PATCH 6/7] Topcliff GbE: Add The common header files [2/2]
From: Masayuki Ohtake @ 2010-04-23 12:01 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 15960 bytes --]
^ permalink raw reply
* [PATCH 7/7] Topcliff GbE: Change The Kconfig and Makefile
From: Masayuki Ohtake @ 2010-04-23 12:01 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
This patch change the Kconfig and Makefile of GbE driver for Topcliff.
The GbE driver needs all patch[1/7 to 7/7].
Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
drivers/net/Kconfig | 5 ++
drivers/net/Makefile | 1
drivers/net/pch_gbe/Makefile | 6
+++++++++++++++++++++++++++++++ 3 files changed, 12 insertions(+)
diff -urN linux-2.6.33.1/drivers/net/Kconfig
topcliff-2.6.33.1/drivers/net/Kconfig
--- linux-2.6.33.1/drivers/net/Kconfig 2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/Kconfig 2010-04-13 00:55:22.000000000
+0900
@@ -1977,6 +1977,11 @@
If you say N, all options in this submenu will be skipped and disabled.
if NETDEV_1000
+config PCH_GBE
+ tristate "PCH Gigabit Ethernet"
+ ---help---
+ This is an gigabit ethernet driver for PCH.
+ resources.
config ACENIC
tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
diff -urN linux-2.6.33.1/drivers/net/Makefile
topcliff-2.6.33.1/drivers/net/Makefile
--- linux-2.6.33.1/drivers/net/Makefile 2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/Makefile 2010-04-13 00:55:22.000000000
+0900
@@ -287,3 +287,4 @@
obj-$(CONFIG_WIMAX) += wimax/
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+obj-$(CONFIG_PCH_GBE) += pch_gbe/
diff -urN linux-2.6.33.1/drivers/net/pch_gbe/Makefile
topcliff-2.6.33.1/drivers/net/pch_gbe/Makefile
--- linux-2.6.33.1/drivers/net/pch_gbe/Makefile 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/net/pch_gbe/Makefile 2010-04-13
00:55:22.000000000 +0900
@@ -0,0 +1,6 @@
+ifeq ($(CONFIG_PCH_GBE_DEBUG_CORE),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_GBE) += pch_gbe.o
+pch_gbe-objs := pch_gbe_mac.o pch_gbe_phy.o pch_gbe_nvm.o pch_gbe_ethtool.o
pch_gbe_plat.o pch_gbe_param.o pch_gbe_api.o pch_gbe_main.o
^ permalink raw reply
* [PATCH 6/7] Topcliff GbE: Add The common header files [1/2]
From: Masayuki Ohtake @ 2010-04-23 12:01 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew
[-- Attachment #1: Type: message/partial, Size: 39242 bytes --]
^ permalink raw reply
* Re: eSwitch management
From: Arnd Bergmann @ 2010-04-23 12:42 UTC (permalink / raw)
To: Anirban Chakraborty
Cc: Scott Feldman, David Miller, netdev@vger.kernel.org,
chrisw@redhat.com, Ameen Rahman, Amit Salecha, Rajesh Borundia
In-Reply-To: <DD92D5A8-1ECC-4440-BE81-ABDCC6847021@qlogic.com>
On Friday 23 April 2010, Anirban Chakraborty wrote:
> On Apr 22, 2010, at 6:29 PM, Scott Feldman wrote:
> > On 4/22/10 5:47 PM, "Scott Feldman" <scofeldm@cisco.com> wrote:
> >>
> >> Are any of these settings covered in DCB? (net/dcb/dcbnl.c). Maybe you can
> >> get a start there? Not sure not knowing your device requirements.
> >
> > Or maybe the RTM_SETLINK IFLA_VF_* ops in include/linux/if_link.h? Those
> > seem like what you're looking for. I'm looking at moving iovnl here as well
> > for port-profile.
>
> It looks like ifla_vf_info does contain most of the data set. But if I use it, what
> NETLINK protocol family should I use in my driver to receive netlink messages? Do I
> need to create a private protocol family?
Your driver should implement the ndo_set_vf_*/ndo_get_vf_* callbacks, not
implement the netlink protocol itself. If there is anything missing in the
existing callbacks that you require for the operation of your driver, you
should send patches to extend the implementation in net/core/rtnetlink.c.
Arnd
^ permalink raw reply
* Re: DDoS attack causing bad effect on conntrack searches
From: Jesper Dangaard Brouer @ 2010-04-23 12:45 UTC (permalink / raw)
To: Patrick McHardy
Cc: Eric Dumazet, Changli Gao, hawk, Linux Kernel Network Hackers,
netfilter-devel, Paul E McKenney
In-Reply-To: <4BD17CF9.4020502@trash.net>
On Fri, 23 Apr 2010, Patrick McHardy wrote:
> That sounds like a good idea. But lets what for Jesper's test results
> before we start fixing this problem :)
I will first have time to perform the tests Monday or Tuesday.
BUT I have just noticed there seems to be a corrolation between conntrack
early_drop and searches. I have upload a new graph:
http://people.netfilter.org/hawk/DDoS/2010-04-12__001/conntrack_early_drop002.png
I have not had time to checkout the code path yet...
Cheers,
Jesper Brouer
--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------
^ permalink raw reply
* Re: [PATCH] RCU: don't turn off lockdep when find suspicious rcu_dereference_check() usage
From: Miles Lane @ 2010-04-23 12:50 UTC (permalink / raw)
To: paulmck
Cc: Vivek Goyal, Eric Paris, Lai Jiangshan, Ingo Molnar,
Peter Zijlstra, LKML, nauman, eric.dumazet, netdev, Jens Axboe,
Gui Jianfeng, Li Zefan
In-Reply-To: <20100422160144.GC2524@linux.vnet.ibm.com>
Hi Paul,
There has been a bit of back and forth, and I am not sure what patches
I should test now.
Could you send me a bundle of whatever needs testing now?
I currently have a build of 2.6.34-rc5-git3 with the same patch I
tested before applied.
I notice a few minor differences in the warnings given. I suspect
these do not indicate
new issues, since the trace from <IRQ> through <EOI> is the same as before.
[ 60.174809] [ INFO: suspicious rcu_dereference_check() usage. ]
[ 60.174812] ---------------------------------------------------
[ 60.174816] net/mac80211/sta_info.c:886 invoked
rcu_dereference_check() without protection!
[ 60.174820]
[ 60.174821] other info that might help us debug this:
[ 60.174822]
[ 60.174825]
[ 60.174826] rcu_scheduler_active = 1, debug_locks = 1
[ 60.174829] no locks held by wpa_supplicant/3973.
[ 60.174832]
[ 60.174833] stack backtrace:
[ 60.174838] Pid: 3973, comm: wpa_supplicant Not tainted 2.6.34-rc5-git3 #19
[ 60.174841] Call Trace:
[ 60.174844] <IRQ> [<ffffffff81067faa>] lockdep_rcu_dereference+0x9d/0xa5
[ 60.174873] [<ffffffffa014e9ae>]
ieee80211_find_sta_by_hw+0x46/0x10f [mac80211]
[ 60.174886] [<ffffffffa014ea8e>] ieee80211_find_sta+0x17/0x19 [mac80211]
[ 60.174902] [<ffffffffa01a60f2>] iwl_tx_queue_reclaim+0xdb/0x1b1 [iwlcore]
[ 60.174909] [<ffffffff81068417>] ? mark_lock+0x2d/0x235
[ 60.174920] [<ffffffffa01d5f1c>] iwl5000_rx_reply_tx+0x4a9/0x556 [iwlagn]
[ 60.174927] [<ffffffff8120a2d3>] ? is_swiotlb_buffer+0x2e/0x3b
[ 60.174936] [<ffffffffa01cebf4>] iwl_rx_handle+0x163/0x2b5 [iwlagn]
[ 60.174943] [<ffffffff810688f0>] ? trace_hardirqs_on_caller+0xfa/0x13f
[ 60.174952] [<ffffffffa01cf3ac>] iwl_irq_tasklet+0x2bb/0x3c0 [iwlagn]
[ 60.174959] [<ffffffff810411df>] tasklet_action+0xa7/0x10f
[ 60.174965] [<ffffffff810421f1>] __do_softirq+0x144/0x252
[ 60.174972] [<ffffffff81003a8c>] call_softirq+0x1c/0x34
[ 60.174977] [<ffffffff810050e4>] do_softirq+0x38/0x80
[ 60.174982] [<ffffffff81041cbe>] irq_exit+0x45/0x94
[ 60.174987] [<ffffffff81004829>] do_IRQ+0xad/0xc4
[ 60.174994] [<ffffffff813cfb13>] ret_from_intr+0x0/0xf
[ 60.174997] <EOI> [<ffffffff810e5114>] ? kmem_cache_alloc+0xa9/0x15f
[ 60.175010] [<ffffffff81342182>] ? __alloc_skb+0x3d/0x155
[ 60.175016] [<ffffffff81342182>] __alloc_skb+0x3d/0x155
[ 60.175023] [<ffffffff8133d237>] sock_alloc_send_pskb+0xc0/0x2e5
[ 60.175030] [<ffffffff8133d46c>] sock_alloc_send_skb+0x10/0x12
[ 60.175036] [<ffffffff813b1ab5>] unix_stream_sendmsg+0x117/0x2e2
[ 60.175044] [<ffffffff811bdca8>] ? avc_has_perm+0x57/0x69
[ 60.175050] [<ffffffff8133b892>] ? sock_aio_write+0x0/0xcf
[ 60.175056] [<ffffffff813392c2>] __sock_sendmsg+0x59/0x64
[ 60.175062] [<ffffffff8133b94d>] sock_aio_write+0xbb/0xcf
[ 60.175069] [<ffffffff810e98b1>] do_sync_readv_writev+0xbc/0xfb
[ 60.175077] [<ffffffff811c1726>] ? selinux_file_permission+0xa2/0xaf
[ 60.175082] [<ffffffff810e9638>] ? copy_from_user+0x2a/0x2c
[ 60.175089] [<ffffffff811baf85>] ? security_file_permission+0x11/0x13
[ 60.175095] [<ffffffff810ea64e>] do_readv_writev+0xa2/0x122
[ 60.175101] [<ffffffff810ead3b>] ? fcheck_files+0x8f/0xc9
[ 60.175107] [<ffffffff810ea70c>] vfs_writev+0x3e/0x49
[ 60.175113] [<ffffffff810ea7f2>] sys_writev+0x45/0x8e
[ 60.175119] [<ffffffff81002b6b>] system_call_fastpath+0x16/0x1b
[ 60.223213] [ INFO: suspicious rcu_dereference_check() usage. ]
[ 60.223216] ---------------------------------------------------
[ 60.223221] net/mac80211/sta_info.c:886 invoked
rcu_dereference_check() without protection!
[ 60.223224]
[ 60.223225] other info that might help us debug this:
[ 60.223227]
[ 60.223230]
[ 60.223230] rcu_scheduler_active = 1, debug_locks = 1
[ 60.223234] no locks held by udisks-daemon/4398.
[ 60.223236]
[ 60.223237] stack backtrace:
[ 60.223242] Pid: 4398, comm: udisks-daemon Not tainted 2.6.34-rc5-git3 #19
[ 60.223245] Call Trace:
[ 60.223249] <IRQ> [<ffffffff81067faa>] lockdep_rcu_dereference+0x9d/0xa5
[ 60.223275] [<ffffffffa014e9fe>]
ieee80211_find_sta_by_hw+0x96/0x10f [mac80211]
[ 60.223288] [<ffffffffa014ea8e>] ieee80211_find_sta+0x17/0x19 [mac80211]
[ 60.223304] [<ffffffffa01a60f2>] iwl_tx_queue_reclaim+0xdb/0x1b1 [iwlcore]
[ 60.223310] [<ffffffff81068417>] ? mark_lock+0x2d/0x235
[ 60.223321] [<ffffffffa01d5f1c>] iwl5000_rx_reply_tx+0x4a9/0x556 [iwlagn]
[ 60.223329] [<ffffffff8120a2d3>] ? is_swiotlb_buffer+0x2e/0x3b
[ 60.223338] [<ffffffffa01cebf4>] iwl_rx_handle+0x163/0x2b5 [iwlagn]
[ 60.223344] [<ffffffff810688f0>] ? trace_hardirqs_on_caller+0xfa/0x13f
[ 60.223353] [<ffffffffa01cf3ac>] iwl_irq_tasklet+0x2bb/0x3c0 [iwlagn]
[ 60.223360] [<ffffffff810411df>] tasklet_action+0xa7/0x10f
[ 60.223367] [<ffffffff810421f1>] __do_softirq+0x144/0x252
[ 60.223374] [<ffffffff81003a8c>] call_softirq+0x1c/0x34
[ 60.223379] [<ffffffff810050e4>] do_softirq+0x38/0x80
[ 60.223384] [<ffffffff81041cbe>] irq_exit+0x45/0x94
[ 60.223389] [<ffffffff81004829>] do_IRQ+0xad/0xc4
[ 60.223396] [<ffffffff813cfb13>] ret_from_intr+0x0/0xf
[ 60.223399] <EOI> [<ffffffff810e34f1>] ? kmem_cache_free+0xb0/0x134
[ 60.223412] [<ffffffff810f391a>] ? putname+0x2d/0x36
[ 60.223417] [<ffffffff810f391a>] putname+0x2d/0x36
[ 60.223423] [<ffffffff810f5536>] user_path_at+0x5f/0x8e
[ 60.223429] [<ffffffff81068671>] ? mark_held_locks+0x52/0x70
[ 60.223435] [<ffffffff810e34ee>] ? kmem_cache_free+0xad/0x134
[ 60.223441] [<ffffffff8106890a>] ? trace_hardirqs_on_caller+0x114/0x13f
[ 60.223447] [<ffffffff81068942>] ? trace_hardirqs_on+0xd/0xf
[ 60.223454] [<ffffffff810ed93f>] vfs_fstatat+0x32/0x5d
[ 60.223460] [<ffffffff810ed9bb>] vfs_lstat+0x19/0x1b
[ 60.223465] [<ffffffff810ed9d7>] sys_newlstat+0x1a/0x38
[ 60.223471] [<ffffffff8106890a>] ? trace_hardirqs_on_caller+0x114/0x13f
[ 60.223477] [<ffffffff813cec00>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 60.223485] [<ffffffff81002b6b>] system_call_fastpath+0x16/0x1b
^ permalink raw reply
* [PATCH] Topcliff PHUB: Add The Packet Hub driver [1/2]
From: Masayuki Ohtake @ 2010-04-23 13:49 UTC (permalink / raw)
To: NETDEV; +Cc: Wang, Yong Y, Wang, Qi, NETDEV, andrew.chih.howe.khor
[-- Attachment #1: Type: message/partial, Size: 39163 bytes --]
^ 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