* Re: [PATCH net-next] MAINTAINERS: b43 updates
From: Larry Finger @ 2010-06-25 2:41 UTC (permalink / raw)
To: Joe Perches
Cc: John W. Linville, Stefano Brivio,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, mb-fseUSCV1ubazQB+pC5nmwQ,
zajec5-Re5JQEeQqe8AvxtiuMwx3w, Gábor Stefanik,
Rafał Miłecki
In-Reply-To: <1277423829.1654.111.camel-AkRN8/LKpobuYGix6ZUp1Q@public.gmane.org>
On 06/24/2010 06:57 PM, Joe Perches wrote:
> On Thu, 2010-06-24 at 18:53 -0500, Larry Finger wrote:
>> I never said that b43 is unmaintained. It is definitely getting much
>> more than "odd fixes".
>
> If Stefano isn't maintaining it, who is?
We are working on that.
Larry
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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
* [PATCH v3] act_mirred: don't clone skb when skb isn't shared
From: Changli Gao @ 2010-06-25 2:25 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: David S. Miller, netdev, Changli Gao
don't clone skb when skb isn't shared
When the tcf_action is TC_ACT_STOLEN, and the skb isn't shared, we don't need
to clone a new skb. As the skb will be freed after this function returns, we
can use it freely once we get a reference to it.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
include/net/sch_generic.h | 11 +++++++++--
net/sched/act_mirred.c | 6 +++---
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index b35301b..977ec06 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -594,9 +594,16 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
}
#ifdef CONFIG_NET_CLS_ACT
-static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask)
+static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
+ int action)
{
- struct sk_buff *n = skb_clone(skb, gfp_mask);
+ struct sk_buff *n;
+
+ if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
+ !skb_shared(skb))
+ n = skb_get(skb);
+ else
+ n = skb_clone(skb, gfp_mask);
if (n) {
n->tc_verd = SET_TC_VERD(n->tc_verd, 0);
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index c0b6863..2e9a7b9 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -169,13 +169,13 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
goto out;
}
- skb2 = skb_act_clone(skb, GFP_ATOMIC);
+ at = G_TC_AT(skb->tc_verd);
+ skb2 = skb_act_clone(skb, GFP_ATOMIC, m->tcf_action);
if (skb2 == NULL)
goto out;
m->tcf_bstats.bytes += qdisc_pkt_len(skb2);
m->tcf_bstats.packets++;
- at = G_TC_AT(skb->tc_verd);
if (!(at & AT_EGRESS)) {
if (m->tcfm_ok_push)
skb_push(skb2, skb2->dev->hard_header_len);
@@ -185,8 +185,8 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
if (m->tcfm_eaction != TCA_EGRESS_MIRROR)
skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
- skb2->dev = dev;
skb2->skb_iif = skb->dev->ifindex;
+ skb2->dev = dev;
dev_queue_xmit(skb2);
err = 0;
^ permalink raw reply related
* RE: [RFC PATCH v7 01/19] Add a new structure for skb buffer from external.
From: Xin, Xiaohui @ 2010-06-25 2:07 UTC (permalink / raw)
To: Herbert Xu, Dong, Eddie
Cc: Stephen Hemminger, netdev@vger.kernel.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org, mst@redhat.com, mingo@elte.hu,
davem@davemloft.net, jdike@linux.intel.com
In-Reply-To: <20100624100836.GA16220@gondor.apana.org.au>
Herbert,
That's why I have sent you the patch for guest virtio-net driver. I reserved 512 bytes in each page, then I can always have the space to copy and avoid the backend memory used up issue.
Thanks
Xiaohui
>-----Original Message-----
>From: Herbert Xu [mailto:herbert@gondor.apana.org.au]
>Sent: Thursday, June 24, 2010 6:09 PM
>To: Dong, Eddie
>Cc: Xin, Xiaohui; Stephen Hemminger; netdev@vger.kernel.org; kvm@vger.kernel.org;
>linux-kernel@vger.kernel.org; mst@redhat.com; mingo@elte.hu; davem@davemloft.net;
>jdike@linux.intel.com
>Subject: Re: [RFC PATCH v7 01/19] Add a new structure for skb buffer from external.
>
>On Wed, Jun 23, 2010 at 06:05:41PM +0800, Dong, Eddie wrote:
>>
>> I mean once the frontend side driver post the buffers to the backend driver, the backend
>driver will "immediately" use that buffers to compose skb or gro_frags and post them to the
>assigned host NIC driver as receive buffers. In that case, if the backend driver recieves a
>packet from the NIC that requires to do copy, it may be unable to find additional free guest
>buffer because all of them are already used by the NIC driver. We have to reserve some guest
>buffers for the possible copy even if the buffer address is not identified by original skb :(
>
>OK I see what you mean. Can you tell me how does Xiaohui's
>previous patch-set deal with this problem?
>
>Thanks,
>--
>Visit Openswan at http://www.openswan.org/
>Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
>Home Page: http://gondor.apana.org.au/~herbert/
>PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] smsc95xx: Add module parameter to override MAC address
From: Simon Horman @ 2010-06-25 1:25 UTC (permalink / raw)
To: Sebastien Jan; +Cc: Steve Glendinning, netdev, linux-omap
In-Reply-To: <1277367254-9345-1-git-send-email-s-jan@ti.com>
On Thu, Jun 24, 2010 at 10:14:14AM +0200, Sebastien Jan wrote:
> Define a new module parameter 'macaddr' to override the MAC address
> fetched either from eeprom, or randomly generated.
>
> The expected MAC address shall be in the 01:23:45:67:89:AB format.
I'm confused as to why this is desirable when the mac address
can already be configured after module insertion via
smsc95xx_netdev_ops.eth_mac_addr().
^ permalink raw reply
* Re: [PATCH 6/8] netpoll: Allow netpoll_setup/cleanup recursion
From: Andrew Morton @ 2010-06-25 1:21 UTC (permalink / raw)
To: Herbert Xu
Cc: Michael S. Tsirkin, Qianfeng Zhang, David S. Miller, netdev,
WANG Cong, Stephen Hemminger, Matt Mackall, Paul E. McKenney,
Peter Zijlstra, Ingo Molnar
In-Reply-To: <E1OMtjk-0006P2-6r@gondolin.me.apana.org.au>
On Fri, 11 Jun 2010 12:12:48 +1000
Herbert Xu <herbert@gondor.hengli.com.au> wrote:
> netpoll: Allow netpoll_setup/cleanup recursion
>
> This patch adds the functions __netpoll_setup/__netpoll_cleanup
> which is designed to be called recursively through ndo_netpoll_seutp.
>
> They must be called with RTNL held, and the caller must initialise
> np->dev and ensure that it has a valid reference count.
>
> ...
>
> -int netpoll_setup(struct netpoll *np)
> +int __netpoll_setup(struct netpoll *np)
> {
> - struct net_device *ndev = NULL;
> - struct in_device *in_dev;
> + struct net_device *ndev = np->dev;
> struct netpoll_info *npinfo;
> const struct net_device_ops *ops;
> unsigned long flags;
> int err;
>
> + if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
> + !ndev->netdev_ops->ndo_poll_controller) {
> + printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
> + np->name, np->dev_name);
> + err = -ENOTSUPP;
> + goto out;
> + }
> +
> + if (!ndev->npinfo) {
> + npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
> + if (!npinfo) {
> + err = -ENOMEM;
> + goto out;
> + }
> +
> + npinfo->rx_flags = 0;
> + INIT_LIST_HEAD(&npinfo->rx_np);
> +
> + spin_lock_init(&npinfo->rx_lock);
> + skb_queue_head_init(&npinfo->arp_tx);
> + skb_queue_head_init(&npinfo->txq);
> + INIT_DELAYED_WORK(&npinfo->tx_work, queue_process);
> +
> + atomic_set(&npinfo->refcnt, 1);
> +
> + ops = np->dev->netdev_ops;
> + if (ops->ndo_netpoll_setup) {
> + err = ops->ndo_netpoll_setup(ndev, npinfo);
> + if (err)
> + goto free_npinfo;
> + }
> + } else {
> + npinfo = ndev->npinfo;
> + atomic_inc(&npinfo->refcnt);
> + }
> +
> + npinfo->netpoll = np;
> +
> + if (np->rx_hook) {
> + spin_lock_irqsave(&npinfo->rx_lock, flags);
> + npinfo->rx_flags |= NETPOLL_RX_ENABLED;
> + list_add_tail(&np->rx, &npinfo->rx_np);
> + spin_unlock_irqrestore(&npinfo->rx_lock, flags);
> + }
> +
> + /* last thing to do is link it to the net device structure */
> + rcu_assign_pointer(ndev->npinfo, npinfo);
> + rtnl_unlock();
And there it is, an unbalanced rtnl_unlock().
This stupid little thing took me over a day's work to find - it's just
been awful.
The user-visible symptom was that a bug in the netpoll code causes the
machine to hang after loading ipv6 (!), because
addrconf_fixup_forwarding()'s rtnl_trylock() kept on failing, and the
restart_syscall() kept on getting restarted, so an initscripts procfs
write just kept banging its head against the excessively-unlocked
mutex.
The mutex code handles an excessively-unlocked mutex (mutex.count==2)
really badly. Some API functions say "its locked", others say "it
isn't", etc.
Maybe it's better with mutex debugging enabled - didn't try that.
Things get pretty user-unfriendly when there's a bug within the
netconsole code itself.
Enabling lockdep simply made the bug cure itself - I suspect the mutex
code's handling of mutexes is different if lockdep is enabled. That
would be pretty bad behaviour from the lockdep code.
I just removed the rtnl_unlock() - I couldn't see much in there which
needed rtnl_locking..
Dave, the fixup should be folded into the original patch please -
otherwise we'll have a machine-hangs-up bisection hole which spans two
weeks work of commits.
^ permalink raw reply
* RE: [RFC PATCH v7 01/19] Add a new structure for skb buffer from external.
From: Dong, Eddie @ 2010-06-25 1:03 UTC (permalink / raw)
To: Herbert Xu
Cc: Xin, Xiaohui, Stephen Hemminger, netdev@vger.kernel.org,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org, mst@redhat.com,
mingo@elte.hu, davem@davemloft.net, jdike@linux.intel.com,
Dong, Eddie, Dong, Eddie
In-Reply-To: <20100624100836.GA16220@gondor.apana.org.au>
Herbert Xu wrote:
> On Wed, Jun 23, 2010 at 06:05:41PM +0800, Dong, Eddie wrote:
>>
>> I mean once the frontend side driver post the buffers to the backend
>> driver, the backend driver will "immediately" use that buffers to
>> compose skb or gro_frags and post them to the assigned host NIC
>> driver as receive buffers. In that case, if the backend driver
>> recieves a packet from the NIC that requires to do copy, it may be
>> unable to find additional free guest buffer because all of them are
>> already used by the NIC driver. We have to reserve some guest
>> buffers for the possible copy even if the buffer address is not
>> identified by original skb :(
>
> OK I see what you mean. Can you tell me how does Xiaohui's
> previous patch-set deal with this problem?
>
> Thanks,
In current patch, each SKB for the assigned device (SRIOV VF or NIC or a complete queue pairs) uses the buffer from guest, so it eliminates copy completely in software and requires hardware to do so. If we can have an additonal place to store the buffer per skb (may cause copy later on), we can do copy later on or re-post the buffer to assigned NIC driver later on. But that may be not very clean either :(
BTW, some hardware may require certain level of packet copy such as for broadcast packets in very old VMDq device, which is not addressed in previous Xiaohui's patch yet. We may address this by implementing an additional virtqueue between guest and host for slow path (broadcast packets only here) with additinal complexity in FE/BE driver.
Thx, Eddie
^ permalink raw reply
* [PATCH net-next 5/6] cnic: Further unify kcq handling code.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1277427522-17306-4-git-send-email-mchan@broadcom.com>
This eliminates some of the duplicate code for the various devices
that require the same basic kcq handling.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 71 +++++++++++++++++++++++++---------------------------
1 files changed, 34 insertions(+), 37 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 8c41fe0..c0cc0d8 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2223,16 +2223,12 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp)
clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags);
}
-static int cnic_service_bnx2(void *data, void *status_blk)
+static u32 cnic_service_bnx2_queues(struct cnic_dev *dev)
{
- struct cnic_dev *dev = data;
struct cnic_local *cp = dev->cnic_priv;
- u32 status_idx = *cp->kcq1.status_idx_ptr;
+ u32 status_idx = (u16) *cp->kcq1.status_idx_ptr;
int kcqe_cnt;
- if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
- return status_idx;
-
cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
@@ -2242,7 +2238,7 @@ static int cnic_service_bnx2(void *data, void *status_blk)
/* Tell compiler that status_blk fields can change. */
barrier();
if (status_idx != *cp->kcq1.status_idx_ptr) {
- status_idx = *cp->kcq1.status_idx_ptr;
+ status_idx = (u16) *cp->kcq1.status_idx_ptr;
cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
} else
break;
@@ -2251,37 +2247,29 @@ static int cnic_service_bnx2(void *data, void *status_blk)
CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
cnic_chk_pkt_rings(cp);
+
return status_idx;
}
-static void cnic_service_bnx2_msix(unsigned long data)
+static int cnic_service_bnx2(void *data, void *status_blk)
{
- struct cnic_dev *dev = (struct cnic_dev *) data;
+ struct cnic_dev *dev = data;
struct cnic_local *cp = dev->cnic_priv;
- struct status_block_msix *status_blk = cp->status_blk.bnx2;
u32 status_idx = *cp->kcq1.status_idx_ptr;
- int kcqe_cnt;
-
- cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
- while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
-
- service_kcqes(dev, kcqe_cnt);
+ if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
+ return status_idx;
- /* Tell compiler that status_blk fields can change. */
- barrier();
- if (status_idx != *cp->kcq1.status_idx_ptr) {
- status_idx = *cp->kcq1.status_idx_ptr;
- cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
- } else
- break;
- }
+ return cnic_service_bnx2_queues(dev);
+}
- CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
+static void cnic_service_bnx2_msix(unsigned long data)
+{
+ struct cnic_dev *dev = (struct cnic_dev *) data;
+ struct cnic_local *cp = dev->cnic_priv;
- cnic_chk_pkt_rings(cp);
+ cp->last_status_idx = cnic_service_bnx2_queues(dev);
- cp->last_status_idx = status_idx;
CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num |
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx);
}
@@ -2338,27 +2326,35 @@ static void cnic_ack_bnx2x_msix(struct cnic_dev *dev)
IGU_INT_DISABLE, 0);
}
-static void cnic_service_bnx2x_bh(unsigned long data)
+static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info)
{
- struct cnic_dev *dev = (struct cnic_dev *) data;
- struct cnic_local *cp = dev->cnic_priv;
- u32 status_idx = *cp->kcq1.status_idx_ptr;
+ u32 last_status = *info->status_idx_ptr;
int kcqe_cnt;
- if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
- return;
-
- while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
+ while ((kcqe_cnt = cnic_get_kcqes(dev, info))) {
service_kcqes(dev, kcqe_cnt);
/* Tell compiler that sblk fields can change. */
barrier();
- if (status_idx == *cp->kcq1.status_idx_ptr)
+ if (last_status == *info->status_idx_ptr)
break;
- status_idx = *cp->kcq1.status_idx_ptr;
+ last_status = *info->status_idx_ptr;
}
+ return last_status;
+}
+
+static void cnic_service_bnx2x_bh(unsigned long data)
+{
+ struct cnic_dev *dev = (struct cnic_dev *) data;
+ struct cnic_local *cp = dev->cnic_priv;
+ u32 status_idx;
+
+ if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
+ return;
+
+ status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1);
CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
@@ -3786,6 +3782,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
cp->kcq1.hw_prod_idx_ptr =
(u16 *) &msblk->status_completion_producer_index;
cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx;
+ cp->kwq_con_idx_ptr = (u16 *) &msblk->status_cmd_consumer_index;
cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT;
cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 4/6] cnic: Restructure kcq processing.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1277427522-17306-3-git-send-email-mchan@broadcom.com>
By doing more work in the common function cnic_get_kcqes(), and
making full use of the kcq_info structure.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 76 +++++++++++++++-------------------------------------
1 files changed, 22 insertions(+), 54 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 948b25b..8c41fe0 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2141,18 +2141,20 @@ static u16 cnic_bnx2x_hw_idx(u16 idx)
return idx;
}
-static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
+static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info)
{
struct cnic_local *cp = dev->cnic_priv;
- u16 i, ri, last;
+ u16 i, ri, hw_prod, last;
struct kcqe *kcqe;
int kcqe_cnt = 0, last_cnt = 0;
- i = ri = last = *sw_prod;
+ i = ri = last = info->sw_prod_idx;
ri &= MAX_KCQ_IDX;
+ hw_prod = *info->hw_prod_idx_ptr;
+ hw_prod = cp->hw_idx(hw_prod);
while ((i != hw_prod) && (kcqe_cnt < MAX_COMPLETED_KCQE)) {
- kcqe = &cp->kcq1.kcq[KCQ_PG(ri)][KCQ_IDX(ri)];
+ kcqe = &info->kcq[KCQ_PG(ri)][KCQ_IDX(ri)];
cp->completed_kcq[kcqe_cnt++] = kcqe;
i = cp->next_idx(i);
ri = i & MAX_KCQ_IDX;
@@ -2162,7 +2164,7 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
}
}
- *sw_prod = last;
+ info->sw_prod_idx = last;
return last_cnt;
}
@@ -2224,10 +2226,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp)
static int cnic_service_bnx2(void *data, void *status_blk)
{
struct cnic_dev *dev = data;
- struct status_block *sblk = status_blk;
struct cnic_local *cp = dev->cnic_priv;
- u32 status_idx = sblk->status_idx;
- u16 hw_prod, sw_prod;
+ u32 status_idx = *cp->kcq1.status_idx_ptr;
int kcqe_cnt;
if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
@@ -2235,29 +2235,20 @@ static int cnic_service_bnx2(void *data, void *status_blk)
cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
- hw_prod = sblk->status_completion_producer_index;
- sw_prod = cp->kcq1.sw_prod_idx;
- while (sw_prod != hw_prod) {
- kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
- if (kcqe_cnt == 0)
- goto done;
+ while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
service_kcqes(dev, kcqe_cnt);
/* Tell compiler that status_blk fields can change. */
barrier();
- if (status_idx != sblk->status_idx) {
- status_idx = sblk->status_idx;
+ if (status_idx != *cp->kcq1.status_idx_ptr) {
+ status_idx = *cp->kcq1.status_idx_ptr;
cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
- hw_prod = sblk->status_completion_producer_index;
} else
break;
}
-done:
- CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
-
- cp->kcq1.sw_prod_idx = sw_prod;
+ CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
cnic_chk_pkt_rings(cp);
return status_idx;
@@ -2268,34 +2259,25 @@ static void cnic_service_bnx2_msix(unsigned long data)
struct cnic_dev *dev = (struct cnic_dev *) data;
struct cnic_local *cp = dev->cnic_priv;
struct status_block_msix *status_blk = cp->status_blk.bnx2;
- u32 status_idx = status_blk->status_idx;
- u16 hw_prod, sw_prod;
+ u32 status_idx = *cp->kcq1.status_idx_ptr;
int kcqe_cnt;
cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
- hw_prod = status_blk->status_completion_producer_index;
- sw_prod = cp->kcq1.sw_prod_idx;
- while (sw_prod != hw_prod) {
- kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
- if (kcqe_cnt == 0)
- goto done;
+ while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
service_kcqes(dev, kcqe_cnt);
/* Tell compiler that status_blk fields can change. */
barrier();
- if (status_idx != status_blk->status_idx) {
- status_idx = status_blk->status_idx;
+ if (status_idx != *cp->kcq1.status_idx_ptr) {
+ status_idx = *cp->kcq1.status_idx_ptr;
cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
- hw_prod = status_blk->status_completion_producer_index;
} else
break;
}
-done:
- CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
- cp->kcq1.sw_prod_idx = sw_prod;
+ CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
cnic_chk_pkt_rings(cp);
@@ -2360,41 +2342,27 @@ static void cnic_service_bnx2x_bh(unsigned long data)
{
struct cnic_dev *dev = (struct cnic_dev *) data;
struct cnic_local *cp = dev->cnic_priv;
- u16 hw_prod, sw_prod;
- struct cstorm_status_block_c *sblk =
- &cp->status_blk.bnx2x->c_status_block;
- u32 status_idx = sblk->status_block_index;
+ u32 status_idx = *cp->kcq1.status_idx_ptr;
int kcqe_cnt;
if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
return;
- hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
- hw_prod = cp->hw_idx(hw_prod);
- sw_prod = cp->kcq1.sw_prod_idx;
- while (sw_prod != hw_prod) {
- kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
- if (kcqe_cnt == 0)
- goto done;
+ while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
service_kcqes(dev, kcqe_cnt);
/* Tell compiler that sblk fields can change. */
barrier();
- if (status_idx == sblk->status_block_index)
+ if (status_idx == *cp->kcq1.status_idx_ptr)
break;
- status_idx = sblk->status_block_index;
- hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
- hw_prod = cp->hw_idx(hw_prod);
+ status_idx = *cp->kcq1.status_idx_ptr;
}
-done:
- CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod + MAX_KCQ_IDX);
+ CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
status_idx, IGU_INT_ENABLE, 1);
-
- cp->kcq1.sw_prod_idx = sw_prod;
}
static int cnic_service_bnx2x(void *data, void *status_blk)
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 1/6] cnic: Fine-tune CID memory space calculation.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
The current code makes assumptions about the CID (context ID) memory
space and starting CID that may not be always correct when firmware
changes. In particular, BNX2_ISCSI_START_CID may not always be fixed.
We now calculate cp->max_cid_space and cp->iscsi_start_cid dynamically
instead of using fixed constants. The unused cp->max_iscsi_conn is also
eliminated.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 32 ++++++++++++++++++--------------
drivers/net/cnic.h | 4 +++-
2 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index e5539f0..23395fa 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -257,7 +257,7 @@ static int cnic_get_l5_cid(struct cnic_local *cp, u32 cid, u32 *l5_cid)
{
u32 i;
- for (i = 0; i < MAX_ISCSI_TBL_SZ; i++) {
+ for (i = 0; i < cp->max_cid_space; i++) {
if (cp->ctx_tbl[i].cid == cid) {
*l5_cid = i;
return 0;
@@ -981,17 +981,10 @@ error:
static int cnic_alloc_bnx2x_context(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- struct cnic_eth_dev *ethdev = cp->ethdev;
int ctx_blk_size = cp->ethdev->ctx_blk_size;
- int total_mem, blks, i, cid_space;
-
- if (BNX2X_ISCSI_START_CID < ethdev->starting_cid)
- return -EINVAL;
-
- cid_space = MAX_ISCSI_TBL_SZ +
- (BNX2X_ISCSI_START_CID - ethdev->starting_cid);
+ int total_mem, blks, i;
- total_mem = BNX2X_CONTEXT_MEM_SIZE * cid_space;
+ total_mem = BNX2X_CONTEXT_MEM_SIZE * cp->max_cid_space;
blks = total_mem / ctx_blk_size;
if (total_mem % ctx_blk_size)
blks++;
@@ -1035,16 +1028,27 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev)
static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
+ struct cnic_eth_dev *ethdev = cp->ethdev;
+ u32 start_cid = ethdev->starting_cid;
int i, j, n, ret, pages;
struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info;
+ cp->max_cid_space = MAX_ISCSI_TBL_SZ;
+ cp->iscsi_start_cid = start_cid;
+ if (start_cid < BNX2X_ISCSI_START_CID) {
+ u32 delta = BNX2X_ISCSI_START_CID - start_cid;
+
+ cp->iscsi_start_cid = BNX2X_ISCSI_START_CID;
+ cp->max_cid_space += delta;
+ }
+
cp->iscsi_tbl = kzalloc(sizeof(struct cnic_iscsi) * MAX_ISCSI_TBL_SZ,
GFP_KERNEL);
if (!cp->iscsi_tbl)
goto error;
cp->ctx_tbl = kzalloc(sizeof(struct cnic_context) *
- MAX_CNIC_L5_CONTEXT, GFP_KERNEL);
+ cp->max_cid_space, GFP_KERNEL);
if (!cp->ctx_tbl)
goto error;
@@ -1053,7 +1057,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_ISCSI;
}
- pages = PAGE_ALIGN(MAX_CNIC_L5_CONTEXT * CNIC_KWQ16_DATA_SIZE) /
+ pages = PAGE_ALIGN(cp->max_cid_space * CNIC_KWQ16_DATA_SIZE) /
PAGE_SIZE;
ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0);
@@ -1061,7 +1065,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
return -ENOMEM;
n = PAGE_SIZE / CNIC_KWQ16_DATA_SIZE;
- for (i = 0, j = 0; i < MAX_ISCSI_TBL_SZ; i++) {
+ for (i = 0, j = 0; i < cp->max_cid_space; i++) {
long off = CNIC_KWQ16_DATA_SIZE * (i % n);
cp->ctx_tbl[i].kwqe_data = kwq_16_dma->pg_arr[j] + off;
@@ -4116,7 +4120,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
u8 sb_id = cp->status_blk_num;
ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ,
- BNX2X_ISCSI_START_CID);
+ cp->iscsi_start_cid);
if (ret)
return -ENOMEM;
diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h
index 08b1235..b7e2f7f 100644
--- a/drivers/net/cnic.h
+++ b/drivers/net/cnic.h
@@ -248,8 +248,10 @@ struct cnic_local {
struct cnic_iscsi *iscsi_tbl;
struct cnic_context *ctx_tbl;
struct cnic_id_tbl cid_tbl;
- int max_iscsi_conn;
atomic_t iscsi_conn;
+ u32 iscsi_start_cid;
+
+ u32 max_cid_space;
/* per connection parameters */
int num_iscsi_tasks;
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 6/6] cnic: Update version to 2.1.3.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1277427522-17306-5-git-send-email-mchan@broadcom.com>
---
drivers/net/cnic_if.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index 0c55177..344c842 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.1.2"
-#define CNIC_MODULE_RELDATE "May 26, 2010"
+#define CNIC_MODULE_VERSION "2.1.3"
+#define CNIC_MODULE_RELDATE "June 24, 2010"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 3/6] cnic: Unify kcq allocation for all devices.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1277427522-17306-2-git-send-email-mchan@broadcom.com>
By creating a common data stucture kcq_info for all devices, the kcq
(kernel completion queue) for all devices can be allocated by common
code.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 143 +++++++++++++++++++++++++++++++--------------------
drivers/net/cnic.h | 19 ++++---
2 files changed, 98 insertions(+), 64 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index bd92a24..948b25b 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -804,7 +804,7 @@ static void cnic_free_resc(struct cnic_dev *dev)
cnic_free_dma(dev, &cp->conn_buf_info);
cnic_free_dma(dev, &cp->kwq_info);
cnic_free_dma(dev, &cp->kwq_16_data_info);
- cnic_free_dma(dev, &cp->kcq_info);
+ cnic_free_dma(dev, &cp->kcq1.dma);
kfree(cp->iscsi_tbl);
cp->iscsi_tbl = NULL;
kfree(cp->ctx_tbl);
@@ -863,6 +863,37 @@ static int cnic_alloc_context(struct cnic_dev *dev)
return 0;
}
+static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info)
+{
+ int err, i, is_bnx2 = 0;
+ struct kcqe **kcq;
+
+ if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags))
+ is_bnx2 = 1;
+
+ err = cnic_alloc_dma(dev, &info->dma, KCQ_PAGE_CNT, is_bnx2);
+ if (err)
+ return err;
+
+ kcq = (struct kcqe **) info->dma.pg_arr;
+ info->kcq = kcq;
+
+ if (is_bnx2)
+ return 0;
+
+ for (i = 0; i < KCQ_PAGE_CNT; i++) {
+ struct bnx2x_bd_chain_next *next =
+ (struct bnx2x_bd_chain_next *) &kcq[i][MAX_KCQE_CNT];
+ int j = i + 1;
+
+ if (j >= KCQ_PAGE_CNT)
+ j = 0;
+ next->addr_hi = (u64) info->dma.pg_map_arr[j] >> 32;
+ next->addr_lo = info->dma.pg_map_arr[j] & 0xffffffff;
+ }
+ return 0;
+}
+
static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -954,10 +985,9 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
goto error;
cp->kwq = (struct kwqe **) cp->kwq_info.pg_arr;
- ret = cnic_alloc_dma(dev, &cp->kcq_info, KCQ_PAGE_CNT, 1);
+ ret = cnic_alloc_kcq(dev, &cp->kcq1);
if (ret)
goto error;
- cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr;
ret = cnic_alloc_context(dev);
if (ret)
@@ -1076,22 +1106,9 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev)
j++;
}
- ret = cnic_alloc_dma(dev, &cp->kcq_info, KCQ_PAGE_CNT, 0);
+ ret = cnic_alloc_kcq(dev, &cp->kcq1);
if (ret)
goto error;
- cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr;
-
- for (i = 0; i < KCQ_PAGE_CNT; i++) {
- struct bnx2x_bd_chain_next *next =
- (struct bnx2x_bd_chain_next *)
- &cp->kcq[i][MAX_KCQE_CNT];
- int j = i + 1;
-
- if (j >= KCQ_PAGE_CNT)
- j = 0;
- next->addr_hi = (u64) cp->kcq_info.pg_map_arr[j] >> 32;
- next->addr_lo = cp->kcq_info.pg_map_arr[j] & 0xffffffff;
- }
pages = PAGE_ALIGN(BNX2X_ISCSI_NUM_CONNECTIONS *
BNX2X_ISCSI_CONN_BUF_SIZE) / PAGE_SIZE;
@@ -2135,7 +2152,7 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
ri &= MAX_KCQ_IDX;
while ((i != hw_prod) && (kcqe_cnt < MAX_COMPLETED_KCQE)) {
- kcqe = &cp->kcq[KCQ_PG(ri)][KCQ_IDX(ri)];
+ kcqe = &cp->kcq1.kcq[KCQ_PG(ri)][KCQ_IDX(ri)];
cp->completed_kcq[kcqe_cnt++] = kcqe;
i = cp->next_idx(i);
ri = i & MAX_KCQ_IDX;
@@ -2219,7 +2236,7 @@ static int cnic_service_bnx2(void *data, void *status_blk)
cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
hw_prod = sblk->status_completion_producer_index;
- sw_prod = cp->kcq_prod_idx;
+ sw_prod = cp->kcq1.sw_prod_idx;
while (sw_prod != hw_prod) {
kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
if (kcqe_cnt == 0)
@@ -2238,9 +2255,9 @@ static int cnic_service_bnx2(void *data, void *status_blk)
}
done:
- CNIC_WR16(dev, cp->kcq_io_addr, sw_prod);
+ CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
- cp->kcq_prod_idx = sw_prod;
+ cp->kcq1.sw_prod_idx = sw_prod;
cnic_chk_pkt_rings(cp);
return status_idx;
@@ -2258,7 +2275,7 @@ static void cnic_service_bnx2_msix(unsigned long data)
cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
hw_prod = status_blk->status_completion_producer_index;
- sw_prod = cp->kcq_prod_idx;
+ sw_prod = cp->kcq1.sw_prod_idx;
while (sw_prod != hw_prod) {
kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
if (kcqe_cnt == 0)
@@ -2277,8 +2294,8 @@ static void cnic_service_bnx2_msix(unsigned long data)
}
done:
- CNIC_WR16(dev, cp->kcq_io_addr, sw_prod);
- cp->kcq_prod_idx = sw_prod;
+ CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
+ cp->kcq1.sw_prod_idx = sw_prod;
cnic_chk_pkt_rings(cp);
@@ -2290,11 +2307,11 @@ done:
static void cnic_doirq(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
- u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
+ u16 prod = cp->kcq1.sw_prod_idx & MAX_KCQ_IDX;
if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
prefetch(cp->status_blk.gen);
- prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+ prefetch(&cp->kcq1.kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
tasklet_schedule(&cp->cnic_irq_task);
}
@@ -2354,7 +2371,7 @@ static void cnic_service_bnx2x_bh(unsigned long data)
hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
hw_prod = cp->hw_idx(hw_prod);
- sw_prod = cp->kcq_prod_idx;
+ sw_prod = cp->kcq1.sw_prod_idx;
while (sw_prod != hw_prod) {
kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
if (kcqe_cnt == 0)
@@ -2373,11 +2390,11 @@ static void cnic_service_bnx2x_bh(unsigned long data)
}
done:
- CNIC_WR16(dev, cp->kcq_io_addr, sw_prod + MAX_KCQ_IDX);
+ CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod + MAX_KCQ_IDX);
cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
status_idx, IGU_INT_ENABLE, 1);
- cp->kcq_prod_idx = sw_prod;
+ cp->kcq1.sw_prod_idx = sw_prod;
}
static int cnic_service_bnx2x(void *data, void *status_blk)
@@ -3711,7 +3728,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
struct cnic_local *cp = dev->cnic_priv;
struct cnic_eth_dev *ethdev = cp->ethdev;
struct status_block *sblk = cp->status_blk.gen;
- u32 val;
+ u32 val, kcq_cid_addr, kwq_cid_addr;
int err;
cnic_set_bnx2_mac(dev);
@@ -3736,7 +3753,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
cnic_init_context(dev, KWQ_CID);
cnic_init_context(dev, KCQ_CID);
- cp->kwq_cid_addr = GET_CID_ADDR(KWQ_CID);
+ kwq_cid_addr = GET_CID_ADDR(KWQ_CID);
cp->kwq_io_addr = MB_GET_CID_ADDR(KWQ_CID) + L5_KRNLQ_HOST_QIDX;
cp->max_kwq_idx = MAX_KWQ_IDX;
@@ -3752,50 +3769,58 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
/* Initialize the kernel work queue context. */
val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE |
(BCM_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ;
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_TYPE, val);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_TYPE, val);
val = (BCM_PAGE_SIZE / sizeof(struct kwqe) - 1) << 16;
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val);
val = ((BCM_PAGE_SIZE / sizeof(struct kwqe)) << 16) | KWQ_PAGE_CNT;
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val);
val = (u32) ((u64) cp->kwq_info.pgtbl_map >> 32);
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_PGTBL_HADDR_HI, val);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_PGTBL_HADDR_HI, val);
val = (u32) cp->kwq_info.pgtbl_map;
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_PGTBL_HADDR_LO, val);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_PGTBL_HADDR_LO, val);
+
+ kcq_cid_addr = GET_CID_ADDR(KCQ_CID);
+ cp->kcq1.io_addr = MB_GET_CID_ADDR(KCQ_CID) + L5_KRNLQ_HOST_QIDX;
- cp->kcq_cid_addr = GET_CID_ADDR(KCQ_CID);
- cp->kcq_io_addr = MB_GET_CID_ADDR(KCQ_CID) + L5_KRNLQ_HOST_QIDX;
+ cp->kcq1.sw_prod_idx = 0;
+ cp->kcq1.hw_prod_idx_ptr =
+ (u16 *) &sblk->status_completion_producer_index;
- cp->kcq_prod_idx = 0;
+ cp->kcq1.status_idx_ptr = (u16 *) &sblk->status_idx;
/* Initialize the kernel complete queue context. */
val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE |
(BCM_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ;
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_TYPE, val);
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_TYPE, val);
val = (BCM_PAGE_SIZE / sizeof(struct kcqe) - 1) << 16;
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val);
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val);
val = ((BCM_PAGE_SIZE / sizeof(struct kcqe)) << 16) | KCQ_PAGE_CNT;
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val);
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val);
- val = (u32) ((u64) cp->kcq_info.pgtbl_map >> 32);
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_PGTBL_HADDR_HI, val);
+ val = (u32) ((u64) cp->kcq1.dma.pgtbl_map >> 32);
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_PGTBL_HADDR_HI, val);
- val = (u32) cp->kcq_info.pgtbl_map;
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_PGTBL_HADDR_LO, val);
+ val = (u32) cp->kcq1.dma.pgtbl_map;
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_PGTBL_HADDR_LO, val);
cp->int_num = 0;
if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
+ struct status_block_msix *msblk = cp->status_blk.bnx2;
u32 sb_id = cp->status_blk_num;
u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id);
+ cp->kcq1.hw_prod_idx_ptr =
+ (u16 *) &msblk->status_completion_producer_index;
+ cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx;
cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT;
- cnic_ctx_wr(dev, cp->kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
- cnic_ctx_wr(dev, cp->kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
+ cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
+ cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);
}
/* Enable Commnad Scheduler notification when we write to the
@@ -4132,28 +4157,34 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
if (ret)
return -ENOMEM;
- cp->kcq_io_addr = BAR_CSTRORM_INTMEM +
+ cp->kcq1.io_addr = BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_PROD_OFFSET(func, 0);
- cp->kcq_prod_idx = 0;
+ cp->kcq1.sw_prod_idx = 0;
+
+ cp->kcq1.hw_prod_idx_ptr =
+ &cp->status_blk.bnx2x->c_status_block.index_values[
+ HC_INDEX_C_ISCSI_EQ_CONS];
+ cp->kcq1.status_idx_ptr =
+ &cp->status_blk.bnx2x->c_status_block.status_block_index;
cnic_get_bnx2x_iscsi_info(dev);
/* Only 1 EQ */
- CNIC_WR16(dev, cp->kcq_io_addr, MAX_KCQ_IDX);
+ CNIC_WR16(dev, cp->kcq1.io_addr, MAX_KCQ_IDX);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_CONS_OFFSET(func, 0), 0);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0),
- cp->kcq_info.pg_map_arr[1] & 0xffffffff);
+ cp->kcq1.dma.pg_map_arr[1] & 0xffffffff);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0) + 4,
- (u64) cp->kcq_info.pg_map_arr[1] >> 32);
+ (u64) cp->kcq1.dma.pg_map_arr[1] >> 32);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0),
- cp->kcq_info.pg_map_arr[0] & 0xffffffff);
+ cp->kcq1.dma.pg_map_arr[0] & 0xffffffff);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0) + 4,
- (u64) cp->kcq_info.pg_map_arr[0] >> 32);
+ (u64) cp->kcq1.dma.pg_map_arr[0] >> 32);
CNIC_WR8(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, 0), 1);
CNIC_WR16(dev, BAR_CSTRORM_INTMEM +
@@ -4381,7 +4412,7 @@ static void cnic_stop_bnx2x_hw(struct cnic_dev *dev)
0);
CNIC_WR(dev, BAR_CSTRORM_INTMEM +
CSTORM_ISCSI_EQ_CONS_OFFSET(cp->func, 0), 0);
- CNIC_WR16(dev, cp->kcq_io_addr, 0);
+ CNIC_WR16(dev, cp->kcq1.io_addr, 0);
cnic_free_resc(dev);
}
diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h
index b7e2f7f..275c361 100644
--- a/drivers/net/cnic.h
+++ b/drivers/net/cnic.h
@@ -169,6 +169,16 @@ struct cnic_context {
} proto;
};
+struct kcq_info {
+ struct cnic_dma dma;
+ struct kcqe **kcq;
+
+ u16 *hw_prod_idx_ptr;
+ u16 sw_prod_idx;
+ u16 *status_idx_ptr;
+ u32 io_addr;
+};
+
struct cnic_local {
spinlock_t cnic_ulp_lock;
@@ -202,9 +212,6 @@ struct cnic_local {
u16 rx_cons;
u16 tx_cons;
- u32 kwq_cid_addr;
- u32 kcq_cid_addr;
-
struct cnic_dma kwq_info;
struct kwqe **kwq;
@@ -218,11 +225,7 @@ struct cnic_local {
u16 *kwq_con_idx_ptr;
u16 kwq_con_idx;
- struct cnic_dma kcq_info;
- struct kcqe **kcq;
-
- u16 kcq_prod_idx;
- u32 kcq_io_addr;
+ struct kcq_info kcq1;
union {
void *gen;
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH net-next 2/6] cnic: Unify IRQ code for all hardware types.
From: Michael Chan @ 2010-06-25 0:58 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1277427522-17306-1-git-send-email-mchan@broadcom.com>
By creating a common cnic_doirq().
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 33 ++++++++++++++++++++-------------
1 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 23395fa..bd92a24 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2188,6 +2188,9 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp)
u16 tx_cons = *cp->tx_cons_ptr;
int comp = 0;
+ if (!test_bit(CNIC_F_CNIC_UP, &cp->dev->flags))
+ return;
+
if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) {
if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags))
comp = cnic_l2_completion(cp);
@@ -2284,20 +2287,28 @@ done:
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx);
}
+static void cnic_doirq(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
+
+ if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+ prefetch(cp->status_blk.gen);
+ prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+
+ tasklet_schedule(&cp->cnic_irq_task);
+ }
+}
+
static irqreturn_t cnic_irq(int irq, void *dev_instance)
{
struct cnic_dev *dev = dev_instance;
struct cnic_local *cp = dev->cnic_priv;
- u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
if (cp->ack_int)
cp->ack_int(dev);
- prefetch(cp->status_blk.gen);
- prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
-
- if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
- tasklet_schedule(&cp->cnic_irq_task);
+ cnic_doirq(dev);
return IRQ_HANDLED;
}
@@ -2373,15 +2384,11 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
{
struct cnic_dev *dev = data;
struct cnic_local *cp = dev->cnic_priv;
- u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
- if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
- prefetch(cp->status_blk.bnx2x);
- prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+ if (!(cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX))
+ cnic_doirq(dev);
- tasklet_schedule(&cp->cnic_irq_task);
- cnic_chk_pkt_rings(cp);
- }
+ cnic_chk_pkt_rings(cp);
return 0;
}
--
1.6.4.GIT
^ permalink raw reply related
* Re: [RFC PATCH v2 1/5] irq: add tracepoint to softirq_raise
From: Koki Sanagi @ 2010-06-25 0:49 UTC (permalink / raw)
To: rostedt
Cc: netdev, davem, scott.a.mcmillan, kaneshige.kenji, izumi.taku,
linux-kernel
In-Reply-To: <1277406914.9181.67.camel@gandalf.stny.rr.com>
Hi Steven,
Sorry, I submitted other patches to only netdev.
I'll resubmit soon all patches to linux-kernel.
(2010/06/25 4:15), Steven Rostedt wrote:
> Hi Koki,
>
> Your subject says 1/5 but I do not see any other patches.
>
>
> On Thu, 2010-06-24 at 17:16 +0900, Koki Sanagi wrote:
>> This patch adds a tracepoint to raising of softirq.
>> This is useful if you want to detect which hard interrupt raise softirq
>> and lets you know a time between raising softirq and performing softirq.
>> Combinating with other tracepoint, it lets us know a process of packets
>> (See patch 0/5).
>>
>> <idle>-0 [001] 241229.957184: softirq_raise: vec=3 [action=NET_RX]
>> <idle>-0 [000] 241229.993399: softirq_raise: vec=1 [action=TIMER]
>> <idle>-0 [000] 241229.993400: softirq_raise: vec=9 [action=RCU]
>>
>> This is a same patch Lai Jiangshan submitted.
>> http://marc.info/?l=linux-kernel&m=126026122728732&w=2
>>
>> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
>> ---
>> include/linux/interrupt.h | 8 +++++++-
>> include/trace/events/irq.h | 34 +++++++++++++++++++++++++++++++---
>> 2 files changed, 38 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
>> index c233113..1cb5726 100644
>> --- a/include/linux/interrupt.h
>> +++ b/include/linux/interrupt.h
>> @@ -18,6 +18,7 @@
>> #include <asm/atomic.h>
>> #include <asm/ptrace.h>
>> #include <asm/system.h>
>> +#include <trace/events/irq.h>
>>
>> /*
>> * These correspond to the IORESOURCE_IRQ_* defines in
>> @@ -402,7 +403,12 @@ asmlinkage void do_softirq(void);
>> asmlinkage void __do_softirq(void);
>> extern void open_softirq(int nr, void (*action)(struct softirq_action *));
>> extern void softirq_init(void);
>> -#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
>> +static inline void __raise_softirq_irqoff(unsigned int nr)
>> +{
>> + trace_softirq_raise(nr);
>> + or_softirq_pending(1UL << nr);
>> +}
>> +
>> extern void raise_softirq_irqoff(unsigned int nr);
>> extern void raise_softirq(unsigned int nr);
>> extern void wakeup_softirqd(void);
>> diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
>> index 0e4cfb6..7cb7435 100644
>> --- a/include/trace/events/irq.h
>> +++ b/include/trace/events/irq.h
>> @@ -5,7 +5,9 @@
>> #define _TRACE_IRQ_H
>>
>> #include <linux/tracepoint.h>
>> -#include <linux/interrupt.h>
>> +
>> +struct irqaction;
>> +struct softirq_action;
>>
>> #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
>> #define show_softirq_name(val) \
>> @@ -82,6 +84,32 @@ TRACE_EVENT(irq_handler_exit,
>> __entry->irq, __entry->ret ? "handled" : "unhandled")
>> );
>>
>> +/**
>> + * softirq_raise - called immediately when a softirq is raised
>> + * @nr: softirq vector number
>> + *
>> + * Tracepoint for tracing when softirq action is raised.
>> + * Also, when used in combination with the softirq_entry tracepoint
>> + * we can determine the softirq raise latency.
>> + */
>> +TRACE_EVENT(softirq_raise,
>> +
>> + TP_PROTO(unsigned int nr),
>> +
>> + TP_ARGS(nr),
>> +
>> + TP_STRUCT__entry(
>> + __field( unsigned int, vec )
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->vec = nr;
>> + ),
>> +
>> + TP_printk("vec=%d [action=%s]", __entry->vec,
>> + show_softirq_name(__entry->vec))
>
> Hmm, is there a way to reuse a DECLARE_EVENT_CLASS here?
>
>> +);
>> +
>> DECLARE_EVENT_CLASS(softirq,
>>
>> TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
>> @@ -89,11 +117,11 @@ DECLARE_EVENT_CLASS(softirq,
>> TP_ARGS(h, vec),
>>
>> TP_STRUCT__entry(
>> - __field( int, vec )
>> + __field( unsigned int, vec )
>> ),
>>
>> TP_fast_assign(
>> - __entry->vec = (int)(h - vec);
>> + __entry->vec = (unsigned int)(h - vec);
>
> Just curious, did you see the original as a bug?
>
> -- Steve
>
>> ),
>>
>> TP_printk("vec=%d [action=%s]", __entry->vec,
>
>
> --
> 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: [PATCH net-next-2.6 2/2] 3c59x: Use fine-grained locks for MII and windowed register access
From: Ben Hutchings @ 2010-06-25 0:45 UTC (permalink / raw)
To: Steffen Klassert; +Cc: David Miller, netdev, Chase Douglas, Arne Nordmark
In-Reply-To: <20100624140057.GJ5570@secunet.com>
[-- Attachment #1: Type: text/plain, Size: 1846 bytes --]
On Thu, 2010-06-24 at 16:00 +0200, Steffen Klassert wrote:
> On Thu, Jun 24, 2010 at 01:57:19PM +0100, Ben Hutchings wrote:
> > >
> > > This adds a lot of calls to spin_lock_irqsave/spin_unlock_irqrestore to many
> > > places where this is not necessary at all. For example during device probe and
> > > device open, window_read/window_write are called multiple times, each time
> > > disabling the interrupts. I'd suggest to have unlocked, locked and irqsave
> > > versions of window_read/window_write and use them in appropriate places.
> >
> > So what? These are not speed-critical. The fast-path functions do
> > acquire the lock just once.
> >
>
> The point is that we should not disable the interrupts if we don't need to
> do so. It is not speed critical for the 3c59x driver but disabling the
> interrupts should be avoided whenever possible. For example during device
> probe and device open we can't race against an interrupt handler because
> the device is not yet running.
>
> An example from vortex_probe1() is:
>
> for (i = 0; i < 6; i++)
> window_write8(vp, dev->dev_addr[i], 2, i);
>
> which expands to someting like:
>
> for (i = 0; i < 6; i++) {
> unsigned long flags;
> spin_lock_irqsave(&vp->window_lock, flags);
> window_set(vp, window);
> iowrite8(dev->dev_addr[i], vp->ioaddr + i);
> spin_unlock_irqrestore(&vp->window_lock, flags);
> return ret;
> }
[...]
I still fail to see why this matters.
The sfc driver which I look after in my day job also uses
spin_lock_irqsave() for each CSR update, when this could be avoided in
the initialisation path. None of the many customers using rt kernels
has ever complained about this. It's just not an important issue.
Ben.
--
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] MAINTAINERS: b43 updates
From: Joe Perches @ 2010-06-24 23:57 UTC (permalink / raw)
To: Larry Finger
Cc: John W. Linville, Stefano Brivio, linux-wireless, netdev,
linux-kernel, mb, zajec5
In-Reply-To: <4C23EFDE.3000702@lwfinger.net>
On Thu, 2010-06-24 at 18:53 -0500, Larry Finger wrote:
> I never said that b43 is unmaintained. It is definitely getting much
> more than "odd fixes".
If Stefano isn't maintaining it, who is?
^ permalink raw reply
* Re: [PATCH net-next] MAINTAINERS: b43 updates
From: Larry Finger @ 2010-06-24 23:53 UTC (permalink / raw)
To: Joe Perches
Cc: John W. Linville, Stefano Brivio, linux-wireless, netdev,
linux-kernel, mb, zajec5
In-Reply-To: <1277423102.1654.107.camel@Joe-Laptop.home>
On 06/24/2010 06:45 PM, Joe Perches wrote:
> On Thu, 2010-06-24 at 14:56 -0500, Larry Finger wrote:
>> The primary arbitrator for patches to the subtle parts of b43 is Michael
>> Buesch; however, he is no longer an official MAINTAINER. I can ACK some
>> things; however, any changes that are associated with my reverse
>> engineering of the Broadcom drivers are off limits.
>
> Add Stefano Brivio's name and email address to CREDITS
> Removed Stefano Brivio's from B43 MAINTAINERS
> Added the b43 development mailing lists
> Changed B43 status to "Odd Fixes"
>
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> CREDITS | 4 ++++
> MAINTAINERS | 5 +++--
> 2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/CREDITS b/CREDITS
> index 72b4878..30215f0 100644
> --- a/CREDITS
> +++ b/CREDITS
> @@ -495,6 +495,10 @@ S: Kopmansg 2
> S: 411 13 Goteborg
> S: Sweden
>
> +N: Stefano Brivio
> +E: stefano.brivio@polimi.it
> +D: B43 wireless driver
> +
> N: Paul Bristow
> E: paul@paulbristow.net
> W: http://paulbristow.net/linux/idefloppy.html
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6d119c9..5bc296c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1225,16 +1225,17 @@ F: include/net/ax25.h
> F: net/ax25/
>
> B43 WIRELESS DRIVER
> -M: Stefano Brivio <stefano.brivio@polimi.it>
> L: linux-wireless@vger.kernel.org
> +L: b43-dev@lists.infradead.org
> W: http://linuxwireless.org/en/users/Drivers/b43
> -S: Maintained
> +S: Odd Fixes
> F: drivers/net/wireless/b43/
>
> B43LEGACY WIRELESS DRIVER
> M: Larry Finger <Larry.Finger@lwfinger.net>
> M: Stefano Brivio <stefano.brivio@polimi.it>
> L: linux-wireless@vger.kernel.org
> +L: b43-dev@lists.infradead.org
> W: http://linuxwireless.org/en/users/Drivers/b43
> S: Maintained
> F: drivers/net/wireless/b43legacy/
NACK. I never said that b43 is unmaintained. It is definitely getting much
more than "odd fixes".
Larry
^ permalink raw reply
* [PATCH] s2io: read rx_packets count from the hardware stats
From: Michal Schmidt @ 2010-06-24 23:32 UTC (permalink / raw)
To: netdev; +Cc: Ramkrishna Vepa, Sivakumar Subramani, Sreenivasa Honnur
Most of the statistics the s2io driver provides in /proc/net/dev
it reads directly from the hardware counters. For some reason it does
not do that for rx_packets. It counts rx_packets purely in software.
A customer reported a bug where in /proc/net/dev the 'multicast' counter
was increasing faster than 'packets' ( = rx_packets in the source code).
This confuses userspace, especially snmpd.
The hardware provides a counter for the total number of received
frames (RMAC_VLD_FRMS) which the driver can use for the rx_packets
statistic. By reading both statistics from the hardware it makes sure
that all multicast frames are included in the total.
The customer tested a patch like this (only modified for RHEL5) with
S2io Inc. Xframe II 10Gbps Ethernet (rev 02)
and it fixed the problem.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/s2io.c | 11 ++++++-----
drivers/net/s2io.h | 1 -
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 668327c..eefc4b2 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -4919,6 +4919,10 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
sp->stats.tx_packets;
sp->stats.tx_packets = le32_to_cpu(stats->tmac_frms);
+ dev->stats.rx_packets += le32_to_cpu(stats->rmac_vld_frms) -
+ sp->stats.rx_packets;
+ sp->stats.rx_packets = le32_to_cpu(stats->rmac_vld_frms);
+
dev->stats.tx_errors += le32_to_cpu(stats->tmac_any_err_frms) -
sp->stats.tx_errors;
sp->stats.tx_errors = le32_to_cpu(stats->tmac_any_err_frms);
@@ -4935,12 +4939,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
sp->stats.rx_length_errors;
sp->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms);
- /* collect per-ring rx_packets and rx_bytes */
- dev->stats.rx_packets = dev->stats.rx_bytes = 0;
+ /* collect per-ring rx_bytes */
+ dev->stats.rx_bytes = 0;
for (i = 0; i < config->rx_ring_num; i++) {
struct ring_info *ring = &mac_control->rings[i];
- dev->stats.rx_packets += ring->rx_packets;
dev->stats.rx_bytes += ring->rx_bytes;
}
@@ -7455,8 +7458,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
}
}
- /* Updating statistics */
- ring_data->rx_packets++;
rxdp->Host_Control = 0;
if (sp->rxd_mode == RXD_MODE_1) {
int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 47c36e0..4da9ab8 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -747,7 +747,6 @@ struct ring_info {
struct buffAdd **ba;
/* per-Ring statistics */
- unsigned long rx_packets;
unsigned long rx_bytes;
} ____cacheline_aligned;
^ permalink raw reply related
* [PATCH net-next] MAINTAINERS: b43 updates
From: Joe Perches @ 2010-06-24 23:45 UTC (permalink / raw)
To: Larry Finger
Cc: John W. Linville, Stefano Brivio, linux-wireless, netdev,
linux-kernel, mb, zajec5
In-Reply-To: <4C23B877.4060209@lwfinger.net>
On Thu, 2010-06-24 at 14:56 -0500, Larry Finger wrote:
> The primary arbitrator for patches to the subtle parts of b43 is Michael
> Buesch; however, he is no longer an official MAINTAINER. I can ACK some
> things; however, any changes that are associated with my reverse
> engineering of the Broadcom drivers are off limits.
Add Stefano Brivio's name and email address to CREDITS
Removed Stefano Brivio's from B43 MAINTAINERS
Added the b43 development mailing lists
Changed B43 status to "Odd Fixes"
Signed-off-by: Joe Perches <joe@perches.com>
---
CREDITS | 4 ++++
MAINTAINERS | 5 +++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/CREDITS b/CREDITS
index 72b4878..30215f0 100644
--- a/CREDITS
+++ b/CREDITS
@@ -495,6 +495,10 @@ S: Kopmansg 2
S: 411 13 Goteborg
S: Sweden
+N: Stefano Brivio
+E: stefano.brivio@polimi.it
+D: B43 wireless driver
+
N: Paul Bristow
E: paul@paulbristow.net
W: http://paulbristow.net/linux/idefloppy.html
diff --git a/MAINTAINERS b/MAINTAINERS
index 6d119c9..5bc296c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1225,16 +1225,17 @@ F: include/net/ax25.h
F: net/ax25/
B43 WIRELESS DRIVER
-M: Stefano Brivio <stefano.brivio@polimi.it>
L: linux-wireless@vger.kernel.org
+L: b43-dev@lists.infradead.org
W: http://linuxwireless.org/en/users/Drivers/b43
-S: Maintained
+S: Odd Fixes
F: drivers/net/wireless/b43/
B43LEGACY WIRELESS DRIVER
M: Larry Finger <Larry.Finger@lwfinger.net>
M: Stefano Brivio <stefano.brivio@polimi.it>
L: linux-wireless@vger.kernel.org
+L: b43-dev@lists.infradead.org
W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained
F: drivers/net/wireless/b43legacy/
^ permalink raw reply related
* Re: [PATCH 3/3] vhost: apply cpumask and cgroup to vhost pollers
From: Sridhar Samudrala @ 2010-06-24 22:45 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Tejun Heo, Oleg Nesterov, netdev, lkml, kvm@vger.kernel.org,
Andrew Morton, Dmitri Vorobiev, Jiri Kosina, Thomas Gleixner,
Ingo Molnar, Andi Kleen
In-Reply-To: <20100624081135.GA937@redhat.com>
On Thu, 2010-06-24 at 11:11 +0300, Michael S. Tsirkin wrote:
> On Sun, May 30, 2010 at 10:25:01PM +0200, Tejun Heo wrote:
> > Apply the cpumask and cgroup of the initializing task to the created
> > vhost poller.
> >
> > Based on Sridhar Samudrala's patch.
> >
> > Cc: Michael S. Tsirkin <mst@redhat.com>
> > Cc: Sridhar Samudrala <samudrala.sridhar@gmail.com>
>
>
> I wanted to apply this, but modpost fails:
> ERROR: "sched_setaffinity" [drivers/vhost/vhost_net.ko] undefined!
> ERROR: "sched_getaffinity" [drivers/vhost/vhost_net.ko] undefined!
>
> Did you try building as a module?
In my original implementation, i had these calls in workqueue.c.
Now that these are moved to vhost.c which can be built as a module,
these symbols need to be exported.
The following patch fixes the build issue with vhost as a module.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
diff --git a/kernel/sched.c b/kernel/sched.c
index 3c2a54f..15a0c6f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4837,6 +4837,7 @@ out_put_task:
put_online_cpus();
return retval;
}
+EXPORT_SYMBOL_GPL(sched_setaffinity);
static int get_user_cpu_mask(unsigned long __user *user_mask_ptr,
unsigned len,
struct cpumask *new_mask)
@@ -4900,6 +4901,7 @@ out_unlock:
return retval;
}
+EXPORT_SYMBOL_GPL(sched_getaffinity);
/**
* sys_sched_getaffinity - get the cpu affinity of a process
> > ---
> > drivers/vhost/vhost.c | 36 +++++++++++++++++++++++++++++++-----
> > 1 file changed, 31 insertions(+), 5 deletions(-)
> >
> > Index: work/drivers/vhost/vhost.c
> > ===================================================================
> > --- work.orig/drivers/vhost/vhost.c
> > +++ work/drivers/vhost/vhost.c
> > @@ -23,6 +23,7 @@
> > #include <linux/highmem.h>
> > #include <linux/slab.h>
> > #include <linux/kthread.h>
> > +#include <linux/cgroup.h>
> >
> > #include <linux/net.h>
> > #include <linux/if_packet.h>
> > @@ -176,12 +177,30 @@ repeat:
> > long vhost_dev_init(struct vhost_dev *dev,
> > struct vhost_virtqueue *vqs, int nvqs)
> > {
> > - struct task_struct *poller;
> > - int i;
> > + struct task_struct *poller = NULL;
> > + cpumask_var_t mask;
> > + int i, ret = -ENOMEM;
> > +
> > + if (!alloc_cpumask_var(&mask, GFP_KERNEL))
> > + goto out;
> >
> > poller = kthread_create(vhost_poller, dev, "vhost-%d", current->pid);
> > - if (IS_ERR(poller))
> > - return PTR_ERR(poller);
> > + if (IS_ERR(poller)) {
> > + ret = PTR_ERR(poller);
> > + goto out;
> > + }
> > +
> > + ret = sched_getaffinity(current->pid, mask);
> > + if (ret)
> > + goto out;
> > +
> > + ret = sched_setaffinity(poller->pid, mask);
> > + if (ret)
> > + goto out;
> > +
> > + ret = cgroup_attach_task_current_cg(poller);
> > + if (ret)
> > + goto out;
> >
> > dev->vqs = vqs;
> > dev->nvqs = nvqs;
> > @@ -202,7 +221,14 @@ long vhost_dev_init(struct vhost_dev *de
> > vhost_poll_init(&dev->vqs[i].poll,
> > dev->vqs[i].handle_kick, POLLIN, dev);
> > }
> > - return 0;
> > +
> > + wake_up_process(poller); /* avoid contributing to loadavg */
> > + ret = 0;
> > +out:
> > + if (ret)
> > + kthread_stop(poller);
> > + free_cpumask_var(mask);
> > + return ret;
> > }
> >
> > /* Caller should have device mutex */
> --
> 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 related
* Re: [PATCH 1/2] syncookies: do not store rcv_wscale in tcp timestamp
From: Hagen Paul Pfeifer @ 2010-06-24 22:14 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev, Ilpo Järvinen
In-Reply-To: <20100624075304.GH27132@Chamillionaire.breakpoint.cc>
* Florian Westphal | 2010-06-24 09:53:04 [+0200]:
>> I speculate that this behavior was and is not correct. I suppose that their is
>> a race between the SYN/ACK where we initial force a particular window scale
>> and the next time where we recalculate the window via tcp_select_initial_window().
>
>Yes, but it is not the only one. We also do a route lookup to get the
>current window size.
Is this critical in any sense? The window size is a pure passive variable, we
do not announce any window information to the peer. I don't get the problem
for the window size.
>> If the user change net.core.rmem_max or net.ipv4.tcp_rmem in between this
>> time, the recalculated window scale (rcv_wscale) can be smaller. But the
>> receiver still operates with the initial window scale and can overshot the
>> granted window - and bang.
>
>Why "bang"?
>Sure, its not nice, but is it such a severe problem that we have to keep
>rcv_wscale around in the timestamp?
IMHO if we want a 100% race free behavior yes.
>> or disable window scaling and don't transmit any scaling option
>> when SYN cookies are active.
>
>No, I would rather see this patch rejected than that.
Sure? SYN cookies are only active if we suffer under acute memory pressure. We
are likely not in the ability to backup large buffer space - why not limit
the window to 2^16 bytes which is sufficient for 99.9999% of the use case?
I do not identify any _real_ advantages to speed up a connection when the
server is under fire.
Another solution is to accept this patch and assume that this race is
rather artificial nature and does not happened. Sure, the race is very
unlikely[TM].
HGN
^ permalink raw reply
* Re: [PATCH] xfrm: check bundle policy existance before dereferencing it
From: David Miller @ 2010-06-24 21:35 UTC (permalink / raw)
To: timo.teras; +Cc: netdev, justinmattock, eric.dumazet, linville, linux-kernel
In-Reply-To: <1277358319-9868-1-git-send-email-timo.teras@iki.fi>
From: Timo Teräs <timo.teras@iki.fi>
Date: Thu, 24 Jun 2010 08:45:19 +0300
> Fix the bundle validation code to not assume having a valid policy.
> When we have multiple transformations for a xfrm policy, the bundle
> instance will be a chain of bundles with only the first one having
> the policy reference. When policy_genid is bumped it will expire the
> first bundle in the chain which is equivalent of expiring the whole
> chain.
>
> Reported-bisected-and-tested-by: Justin P. Mattock <justinmattock@gmail.com>
> Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Applied.
^ permalink raw reply
* Re: [PATCH net-next-2.6 2/5] sfc: Implement message level control
From: David Miller @ 2010-06-24 21:33 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
In-Reply-To: <1277349138.26161.144.camel@localhost>
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Thu, 24 Jun 2010 04:12:18 +0100
> I'm hoping you're going to apply
> <http://patchwork.ozlabs.org/patch/56308> first.
I'm hoping that you will always tell me about such dependencies
in the future.
I always work my queue out of order. If I'm heavily backlogged like
I am now, I'll sometimes apply much "simpler" to review patch
sets before more difficult ones, even if the "difficult" ones are
older.
Never assume anything, always state explicitly what tree something
is for and whether dependencies exist for things as-yet not applied.
Your style of assuming things makes life real difficult for me.
^ permalink raw reply
* [net-next-2.6 PATCH 10/10] enic: Clean ups
From: Vasanthy Kolluri @ 2010-06-24 20:52 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
1) Update copyright
2) Fix hardware queue descriptor field size CQ_ENET_RQ_DESC_FCOE_SOF_BITS
3) Include rtnetlink.h instead of if_link.h
4) Selectively flush writes to interrupt mask register
5) Use pci_enable_device_mem
6) Remove unused variables and header files
7) Fix size mismatch between memory alloc and free operations of a variable
8) Check for non null arguments to vic_provinfo_alloc
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/cq_desc.h | 2 +-
drivers/net/enic/cq_enet_desc.h | 4 ++--
drivers/net/enic/enic.h | 4 ++--
drivers/net/enic/enic_main.c | 11 ++++++-----
drivers/net/enic/enic_res.c | 2 +-
drivers/net/enic/enic_res.h | 2 +-
drivers/net/enic/rq_enet_desc.h | 2 +-
drivers/net/enic/vnic_cq.c | 2 +-
drivers/net/enic/vnic_cq.h | 2 +-
drivers/net/enic/vnic_dev.c | 25 +++----------------------
drivers/net/enic/vnic_dev.h | 2 +-
drivers/net/enic/vnic_devcmd.h | 2 +-
drivers/net/enic/vnic_enet.h | 2 +-
drivers/net/enic/vnic_intr.c | 2 +-
drivers/net/enic/vnic_intr.h | 8 ++++++--
drivers/net/enic/vnic_nic.h | 2 +-
drivers/net/enic/vnic_resource.h | 2 +-
drivers/net/enic/vnic_rq.c | 4 +---
drivers/net/enic/vnic_rq.h | 2 +-
| 2 +-
drivers/net/enic/vnic_stats.h | 2 +-
drivers/net/enic/vnic_vic.c | 3 +++
drivers/net/enic/vnic_wq.c | 3 +--
drivers/net/enic/vnic_wq.h | 2 +-
drivers/net/enic/wq_enet_desc.h | 2 +-
25 files changed, 41 insertions(+), 55 deletions(-)
diff --git a/drivers/net/enic/cq_desc.h b/drivers/net/enic/cq_desc.h
index 1eb289f..d6dd1b4 100644
--- a/drivers/net/enic/cq_desc.h
+++ b/drivers/net/enic/cq_desc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/cq_enet_desc.h b/drivers/net/enic/cq_enet_desc.h
index f2d98bb..c2c0680 100644
--- a/drivers/net/enic/cq_enet_desc.h
+++ b/drivers/net/enic/cq_enet_desc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -82,7 +82,7 @@ struct cq_enet_rq_desc {
((1 << CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS) - 1)
#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_SHIFT 13
-#define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4
+#define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 8
#define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \
((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1)
#define CQ_ENET_RQ_DESC_FCOE_EOF_BITS 8
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 7280314..f239aa8 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -33,7 +33,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
#define DRV_VERSION "1.4.1.1"
-#define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc"
+#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index eda5530..6c6795b 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -29,12 +29,12 @@
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
-#include <linux/if_link.h>
#include <linux/ethtool.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
+#include <linux/rtnetlink.h>
#include <net/ip6_checksum.h>
#include "cq_enet_desc.h"
@@ -1799,8 +1799,10 @@ static int enic_stop(struct net_device *netdev)
unsigned int i;
int err;
- for (i = 0; i < enic->intr_count; i++)
+ for (i = 0; i < enic->intr_count; i++) {
vnic_intr_mask(&enic->intr[i]);
+ (void)vnic_intr_masked(&enic->intr[i]); /* flush write */
+ }
enic_synchronize_irqs(enic);
@@ -1810,7 +1812,6 @@ static int enic_stop(struct net_device *netdev)
napi_disable(&enic->napi);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
-
enic_dev_del_station_addr(enic);
for (i = 0; i < enic->wq_count; i++) {
@@ -2299,7 +2300,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
/* Setup PCI resources
*/
- err = pci_enable_device(pdev);
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(dev, "Cannot enable PCI device, aborting\n");
goto err_out_free_netdev;
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 2cc7e27..29ede8a 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 8b25a07..83bd172 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/rq_enet_desc.h b/drivers/net/enic/rq_enet_desc.h
index a06e649..e6dd309 100644
--- a/drivers/net/enic/rq_enet_desc.h
+++ b/drivers/net/enic/rq_enet_desc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_cq.c b/drivers/net/enic/vnic_cq.c
index 326ea40..b86d6ef 100644
--- a/drivers/net/enic/vnic_cq.c
+++ b/drivers/net/enic/vnic_cq.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_cq.h b/drivers/net/enic/vnic_cq.h
index 114763c..552d3da 100644
--- a/drivers/net/enic/vnic_cq.h
+++ b/drivers/net/enic/vnic_cq.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 662123c..6a5b578 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -23,7 +23,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/if_ether.h>
-#include <linux/slab.h>
#include "vnic_resource.h"
#include "vnic_devcmd.h"
@@ -41,8 +40,6 @@ struct vnic_res {
unsigned int count;
};
-#define VNIC_DEV_CAP_INIT 0x0001
-
struct vnic_dev {
void *priv;
struct pci_dev *pdev;
@@ -53,13 +50,11 @@ struct vnic_dev {
struct vnic_devcmd_notify notify_copy;
dma_addr_t notify_pa;
u32 notify_sz;
- u32 *linkstatus;
dma_addr_t linkstatus_pa;
struct vnic_stats *stats;
dma_addr_t stats_pa;
struct vnic_devcmd_fw_info *fw_info;
dma_addr_t fw_info_pa;
- u32 cap_flags;
enum vnic_proxy_type proxy;
u32 proxy_index;
u64 args[VNIC_DEVCMD_NARGS];
@@ -279,7 +274,6 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
/* PCI-e target device is gone */
return -ENODEV;
}
-
if (status & STAT_BUSY) {
pr_err("Busy devcmd %d\n", _CMD_N(cmd));
return -EBUSY;
@@ -852,7 +846,7 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
int wait = 1000;
int r = 0;
- if (vdev->cap_flags & VNIC_DEV_CAP_INIT)
+ if (vnic_dev_capable(vdev, CMD_INIT))
r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
else {
vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
@@ -919,9 +913,6 @@ int vnic_dev_deinit(struct vnic_dev *vdev)
int vnic_dev_link_status(struct vnic_dev *vdev)
{
- if (vdev->linkstatus)
- return *vdev->linkstatus;
-
if (!vnic_dev_notify_ready(vdev))
return 0;
@@ -996,14 +987,9 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
sizeof(struct vnic_devcmd_notify),
vdev->notify,
vdev->notify_pa);
- if (vdev->linkstatus)
- pci_free_consistent(vdev->pdev,
- sizeof(u32),
- vdev->linkstatus,
- vdev->linkstatus_pa);
if (vdev->stats)
pci_free_consistent(vdev->pdev,
- sizeof(struct vnic_dev),
+ sizeof(struct vnic_stats),
vdev->stats, vdev->stats_pa);
if (vdev->fw_info)
pci_free_consistent(vdev->pdev,
@@ -1033,11 +1019,6 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
if (!vdev->devcmd)
goto err_out;
- vdev->cap_flags = 0;
-
- if (vnic_dev_capable(vdev, CMD_INIT))
- vdev->cap_flags |= VNIC_DEV_CAP_INIT;
-
return vdev;
err_out:
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index cfdaa69..3a61873 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index e6c80c7..2066175 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 42baaa1..3b32912 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c
index 416eae7..52ab61a 100644
--- a/drivers/net/enic/vnic_intr.c
+++ b/drivers/net/enic/vnic_intr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h
index 2fe6c63..09dc0b7 100644
--- a/drivers/net/enic/vnic_intr.h
+++ b/drivers/net/enic/vnic_intr.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -61,7 +61,11 @@ static inline void vnic_intr_unmask(struct vnic_intr *intr)
static inline void vnic_intr_mask(struct vnic_intr *intr)
{
iowrite32(1, &intr->ctrl->mask);
- (void)ioread32(&intr->ctrl->mask);
+}
+
+static inline int vnic_intr_masked(struct vnic_intr *intr)
+{
+ return ioread32(&intr->ctrl->mask);
}
static inline void vnic_intr_return_credits(struct vnic_intr *intr,
diff --git a/drivers/net/enic/vnic_nic.h b/drivers/net/enic/vnic_nic.h
index cf80ab4..995a50d 100644
--- a/drivers/net/enic/vnic_nic.h
+++ b/drivers/net/enic/vnic_nic.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h
index b61c22a..810287b 100644
--- a/drivers/net/enic/vnic_resource.h
+++ b/drivers/net/enic/vnic_resource.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index 061a26f..4d8e546 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -22,7 +22,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_rq.h"
@@ -209,7 +208,6 @@ void vnic_rq_clean(struct vnic_rq *rq,
/* Hardware surprise removal: reset fetch_index */
fetch_index = 0;
}
-
rq->to_use = rq->to_clean =
&rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
[fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index 8f0fb78..2dc48f9 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
--git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h
index 5fbb3c9..f62d187 100644
--- a/drivers/net/enic/vnic_rss.h
+++ b/drivers/net/enic/vnic_rss.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_stats.h b/drivers/net/enic/vnic_stats.h
index 9ff9614..77750ec 100644
--- a/drivers/net/enic/vnic_stats.h
+++ b/drivers/net/enic/vnic_stats.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c
index 0a35085..197c9d2 100644
--- a/drivers/net/enic/vnic_vic.c
+++ b/drivers/net/enic/vnic_vic.c
@@ -27,6 +27,9 @@ struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type)
{
struct vic_provinfo *vp;
+ if (!oui)
+ return NULL;
+
vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags);
if (!vp)
return NULL;
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index 3ab7fa5..5c84bb8 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
@@ -22,7 +22,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_wq.h"
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h
index 1c82139..94ac462 100644
--- a/drivers/net/enic/vnic_wq.h
+++ b/drivers/net/enic/vnic_wq.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
diff --git a/drivers/net/enic/wq_enet_desc.h b/drivers/net/enic/wq_enet_desc.h
index 483596c..c7021e3 100644
--- a/drivers/net/enic/wq_enet_desc.h
+++ b/drivers/net/enic/wq_enet_desc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
^ permalink raw reply related
* [net-next-2.6 PATCH 09/10] enic: Bug Fix: Handle surprise hardware removals
From: Vasanthy Kolluri @ 2010-06-24 20:52 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Handle surprise hardware removals gracefully during devcmd issue and init,
cleanup of queues.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/vnic_dev.c | 9 +++++++++
drivers/net/enic/vnic_rq.c | 13 +++++++++++--
drivers/net/enic/vnic_wq.c | 2 --
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 180912f..662123c 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -275,6 +275,11 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
int err;
status = ioread32(&devcmd->status);
+ if (status == 0xFFFFFFFF) {
+ /* PCI-e target device is gone */
+ return -ENODEV;
+ }
+
if (status & STAT_BUSY) {
pr_err("Busy devcmd %d\n", _CMD_N(cmd));
return -EBUSY;
@@ -296,6 +301,10 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
udelay(100);
status = ioread32(&devcmd->status);
+ if (status == 0xFFFFFFFF) {
+ /* PCI-e target device is gone */
+ return -ENODEV;
+ }
if (!(status & STAT_BUSY)) {
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index 45cfc79..061a26f 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -146,6 +146,11 @@ void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
/* Use current fetch_index as the ring starting point */
fetch_index = ioread32(&rq->ctrl->fetch_index);
+ if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */
+ /* Hardware surprise removal: reset fetch_index */
+ fetch_index = 0;
+ }
+
vnic_rq_init_start(rq, cq_index,
fetch_index, fetch_index,
error_interrupt_enable,
@@ -187,8 +192,6 @@ void vnic_rq_clean(struct vnic_rq *rq,
u32 fetch_index;
unsigned int count = rq->ring.desc_count;
- BUG_ON(ioread32(&rq->ctrl->enable));
-
buf = rq->to_clean;
while (vnic_rq_desc_used(rq) > 0) {
@@ -201,6 +204,12 @@ void vnic_rq_clean(struct vnic_rq *rq,
/* Use current fetch_index as the ring starting point */
fetch_index = ioread32(&rq->ctrl->fetch_index);
+
+ if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */
+ /* Hardware surprise removal: reset fetch_index */
+ fetch_index = 0;
+ }
+
rq->to_use = rq->to_clean =
&rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
[fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index 6c4d4f7..3ab7fa5 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -178,8 +178,6 @@ void vnic_wq_clean(struct vnic_wq *wq,
{
struct vnic_wq_buf *buf;
- BUG_ON(ioread32(&wq->ctrl->enable));
-
buf = wq->to_clean;
while (vnic_wq_desc_used(wq) > 0) {
^ permalink raw reply related
* [net-next-2.6 PATCH 08/10] enic: Feature Add: Add loopback capability to enic devices
From: Vasanthy Kolluri @ 2010-06-24 20:51 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Hardware has the loopback capability to queue the packets transmitted from
a device to the receive queue of the same device. enic now supports the
loopback capability.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/enic.h | 2 ++
drivers/net/enic/enic_main.c | 42 +++++++++++++++++++++++++++---------------
drivers/net/enic/enic_res.c | 1 +
drivers/net/enic/enic_res.h | 25 +++++++++++++------------
drivers/net/enic/vnic_enet.h | 2 ++
5 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 3588ef5..7280314 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -110,6 +110,8 @@ struct enic {
spinlock_t wq_lock[ENIC_WQ_MAX];
unsigned int wq_count;
struct vlan_group *vlan_group;
+ u16 loop_enable;
+ u16 loop_tag;
/* receive queue cache line section */
____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 413e362..eda5530 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -594,7 +594,7 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data)
static inline void enic_queue_wq_skb_cont(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- unsigned int len_left)
+ unsigned int len_left, int loopback)
{
skb_frag_t *frag;
@@ -606,13 +606,14 @@ static inline void enic_queue_wq_skb_cont(struct enic *enic,
frag->page_offset, frag->size,
PCI_DMA_TODEVICE),
frag->size,
- (len_left == 0)); /* EOP? */
+ (len_left == 0), /* EOP? */
+ loopback);
}
}
static inline void enic_queue_wq_skb_vlan(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int head_len = skb_headlen(skb);
unsigned int len_left = skb->len - head_len;
@@ -628,15 +629,15 @@ static inline void enic_queue_wq_skb_vlan(struct enic *enic,
head_len, PCI_DMA_TODEVICE),
head_len,
vlan_tag_insert, vlan_tag,
- eop);
+ eop, loopback);
if (!eop)
- enic_queue_wq_skb_cont(enic, wq, skb, len_left);
+ enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
}
static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int head_len = skb_headlen(skb);
unsigned int len_left = skb->len - head_len;
@@ -656,15 +657,15 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
csum_offset,
hdr_len,
vlan_tag_insert, vlan_tag,
- eop);
+ eop, loopback);
if (!eop)
- enic_queue_wq_skb_cont(enic, wq, skb, len_left);
+ enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
}
static inline void enic_queue_wq_skb_tso(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int frag_len_left = skb_headlen(skb);
unsigned int len_left = skb->len - frag_len_left;
@@ -701,7 +702,7 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
len,
mss, hdr_len,
vlan_tag_insert, vlan_tag,
- eop && (len == frag_len_left));
+ eop && (len == frag_len_left), loopback);
frag_len_left -= len;
offset += len;
}
@@ -727,7 +728,8 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
dma_addr,
len,
(len_left == 0) &&
- (len == frag_len_left)); /* EOP? */
+ (len == frag_len_left), /* EOP? */
+ loopback);
frag_len_left -= len;
offset += len;
}
@@ -740,22 +742,26 @@ static inline void enic_queue_wq_skb(struct enic *enic,
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int vlan_tag = 0;
int vlan_tag_insert = 0;
+ int loopback = 0;
if (enic->vlan_group && vlan_tx_tag_present(skb)) {
/* VLAN tag from trunking driver */
vlan_tag_insert = 1;
vlan_tag = vlan_tx_tag_get(skb);
+ } else if (enic->loop_enable) {
+ vlan_tag = enic->loop_tag;
+ loopback = 1;
}
if (mss)
enic_queue_wq_skb_tso(enic, wq, skb, mss,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
else if (skb->ip_summed == CHECKSUM_PARTIAL)
enic_queue_wq_skb_csum_l4(enic, wq, skb,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
else
enic_queue_wq_skb_vlan(enic, wq, skb,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
}
/* netif_tx_lock held, process context with BHs disabled, or BH */
@@ -1275,7 +1281,7 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
struct enic *enic = vnic_dev_priv(rq->vdev);
struct net_device *netdev = enic->netdev;
struct sk_buff *skb;
- unsigned int len = netdev->mtu + ETH_HLEN;
+ unsigned int len = netdev->mtu + VLAN_ETH_HLEN;
unsigned int os_buf_index = 0;
dma_addr_t dma_addr;
@@ -2441,6 +2447,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netdev->ethtool_ops = &enic_ethtool_ops;
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ if (ENIC_SETTING(enic, LOOP)) {
+ netdev->features &= ~NETIF_F_HW_VLAN_TX;
+ enic->loop_enable = 1;
+ enic->loop_tag = enic->config.loop_tag;
+ dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
+ }
if (ENIC_SETTING(enic, TXCSUM))
netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
if (ENIC_SETTING(enic, TSO))
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 478928b..2cc7e27 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -70,6 +70,7 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(intr_timer_type);
GET_CONFIG(intr_mode);
GET_CONFIG(intr_timer_usec);
+ GET_CONFIG(loop_tag);
c->wq_desc_count =
min_t(u32, ENIC_MAX_WQ_DESCS,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 3f6e039..8b25a07 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -43,7 +43,7 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int mss_or_csum_offset, unsigned int hdr_len,
int vlan_tag_insert, unsigned int vlan_tag,
- int offload_mode, int cq_entry, int sop, int eop)
+ int offload_mode, int cq_entry, int sop, int eop, int loopback)
{
struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
@@ -56,61 +56,62 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
0, /* fcoe_encap */
(u8)vlan_tag_insert,
(u16)vlan_tag,
- 0 /* loopback */);
+ (u8)loopback);
vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
}
static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq,
- void *os_buf, dma_addr_t dma_addr, unsigned int len, int eop)
+ void *os_buf, dma_addr_t dma_addr, unsigned int len,
+ int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
0, 0, 0, 0, 0,
- eop, 0 /* !SOP */, eop);
+ eop, 0 /* !SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc(struct vnic_wq *wq, void *os_buf,
dma_addr_t dma_addr, unsigned int len, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
0, 0, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_csum(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
int ip_csum, int tcpudp_csum, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
(ip_csum ? 1 : 0) + (tcpudp_csum ? 2 : 0),
0, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_csum_l4(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int csum_offset, unsigned int hdr_len,
- int vlan_tag_insert, unsigned int vlan_tag, int eop)
+ int vlan_tag_insert, unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
csum_offset, hdr_len, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM_L4,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_tso(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int mss, unsigned int hdr_len, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
mss, hdr_len, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_TSO,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_rq_desc(struct vnic_rq *rq,
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 8eeb675..42baaa1 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -35,6 +35,7 @@ struct vnic_enet_config {
u8 intr_mode;
char devname[16];
u32 intr_timer_usec;
+ u16 loop_tag;
};
#define VENETF_TSO 0x1 /* TSO enabled */
@@ -48,5 +49,6 @@ struct vnic_enet_config {
#define VENETF_RSSHASH_TCPIPV6 0x100 /* Hash on TCP + IPv6 fields */
#define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */
#define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */
+#define VENETF_LOOP 0x800 /* Loopback enabled */
#endif /* _VNIC_ENIC_H_ */
^ permalink raw reply related
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