* [PATCH 2/4] ipv6: Get rid of rt6i_nexthop macro.
From: David Miller @ 2011-07-18 8:25 UTC (permalink / raw)
To: netdev
It just makes it harder to see 1) what the code is doing
and 2) grep for all users of dst{->,.}neighbour
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/ip6_fib.h | 1 -
net/ipv6/addrconf.c | 2 +-
net/ipv6/ip6_fib.c | 2 +-
net/ipv6/ndisc.c | 4 ++--
net/ipv6/route.c | 30 +++++++++++++++---------------
5 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 477ef75..5735a0f 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -87,7 +87,6 @@ struct rt6_info {
struct dst_entry dst;
#define rt6i_dev dst.dev
-#define rt6i_nexthop dst.neighbour
#define rt6i_expires dst.expires
/*
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index fc6d377..48cd03d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
* layer address of our nexhop router
*/
- if (rt->rt6i_nexthop == NULL)
+ if (rt->dst.neighbour == NULL)
ifa->flags &= ~IFA_F_OPTIMISTIC;
ifa->idev = idev;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 3030bdf..158df23 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
RT6_TRACE("aging clone %p\n", rt);
return -1;
} else if ((rt->rt6i_flags & RTF_GATEWAY) &&
- (!(rt->rt6i_nexthop->flags & NTF_ROUTER))) {
+ (!(rt->dst.neighbour->flags & NTF_ROUTER))) {
RT6_TRACE("purging route %p via non-router but gateway\n",
rt);
return -1;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index e08ce55..a997d41 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1238,7 +1238,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
if (rt)
- neigh = rt->rt6i_nexthop;
+ neigh = rt->dst.neighbour;
if (rt && lifetime == 0) {
neigh_clone(neigh);
@@ -1259,7 +1259,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
return;
}
- neigh = rt->rt6i_nexthop;
+ neigh = rt->dst.neighbour;
if (neigh == NULL) {
ND_PRINTK0(KERN_ERR
"ICMPv6 RA: %s() got default router without neighbour.\n",
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f032d77..c1515a3 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -356,7 +356,7 @@ out:
#ifdef CONFIG_IPV6_ROUTER_PREF
static void rt6_probe(struct rt6_info *rt)
{
- struct neighbour *neigh = rt ? rt->rt6i_nexthop : NULL;
+ struct neighbour *neigh = rt ? rt->dst.neighbour : NULL;
/*
* Okay, this does not seem to be appropriate
* for now, however, we need to check if it
@@ -404,7 +404,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif)
static inline int rt6_check_neigh(struct rt6_info *rt)
{
- struct neighbour *neigh = rt->rt6i_nexthop;
+ struct neighbour *neigh = rt->dst.neighbour;
int m;
if (rt->rt6i_flags & RTF_NONEXTHOP ||
!(rt->rt6i_flags & RTF_GATEWAY))
@@ -745,7 +745,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add
dst_free(&rt->dst);
return NULL;
}
- rt->rt6i_nexthop = neigh;
+ rt->dst.neighbour = neigh;
}
@@ -760,7 +760,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_a
rt->rt6i_dst.plen = 128;
rt->rt6i_flags |= RTF_CACHE;
rt->dst.flags |= DST_HOST;
- rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop);
+ rt->dst.neighbour = neigh_clone(ort->dst.neighbour);
}
return rt;
}
@@ -794,7 +794,7 @@ restart:
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);
- if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!rt->dst.neighbour && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -1058,7 +1058,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
}
rt->rt6i_idev = idev;
- rt->rt6i_nexthop = neigh;
+ rt->dst.neighbour = neigh;
atomic_set(&rt->dst.__refcnt, 1);
dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
rt->dst.output = ip6_output;
@@ -1338,10 +1338,10 @@ int ip6_route_add(struct fib6_config *cfg)
rt->rt6i_prefsrc.plen = 0;
if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
- rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
- if (IS_ERR(rt->rt6i_nexthop)) {
- err = PTR_ERR(rt->rt6i_nexthop);
- rt->rt6i_nexthop = NULL;
+ rt->dst.neighbour = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
+ if (IS_ERR(rt->dst.neighbour)) {
+ err = PTR_ERR(rt->dst.neighbour);
+ rt->dst.neighbour = NULL;
goto out;
}
}
@@ -1590,7 +1590,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
nrt->dst.flags |= DST_HOST;
ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key);
- nrt->rt6i_nexthop = neigh_clone(neigh);
+ nrt->dst.neighbour = neigh_clone(neigh);
if (ip6_ins_rt(nrt))
goto out;
@@ -1670,7 +1670,7 @@ again:
1. It is connected route. Action: COW
2. It is gatewayed route or NONEXTHOP route. Action: clone it.
*/
- if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!rt->dst.neighbour && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, daddr, saddr);
else
nrt = rt6_alloc_clone(rt, daddr);
@@ -2035,7 +2035,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
return ERR_CAST(neigh);
}
- rt->rt6i_nexthop = neigh;
+ rt->dst.neighbour = neigh;
ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
rt->rt6i_dst.plen = 128;
@@ -2594,8 +2594,8 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
seq_puts(m, "00000000000000000000000000000000 00 ");
#endif
- if (rt->rt6i_nexthop) {
- seq_printf(m, "%pi6", rt->rt6i_nexthop->primary_key);
+ if (rt->dst.neighbour) {
+ seq_printf(m, "%pi6", rt->dst.neighbour->primary_key);
} else {
seq_puts(m, "00000000000000000000000000000000");
}
--
1.7.6
^ permalink raw reply related
* [PATCH 39/45] bna: RX Path Changes
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Disable and enable interrupts from the same polling context to prevent
reordering in Rx path.
- Set coalescing timer to 0 within bnad_poll_cq().
- Move preempt_disable()/preempt_enable() calls from bnad_poll_cq() to
bnad_napi_poll_rx() and bnad_poll().
- Add Rx NAPI debug counters.
- Add macros to drop skb and return, to unmap skb. Check and drop illegal
skbs in transmit path.
- Check for single frame TSO skbs and send them out as non-TSO.
- Put memory barrier after bna_txq_prod_indx_doorbell()
- Add tx_skb sounters for dropped frames in transmit path.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bnad.c | 325 ++++++++++++++++++++++++------------------------
drivers/net/bna/bnad.h | 36 +++++-
2 files changed, 199 insertions(+), 162 deletions(-)
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index f6b7401..d4de429 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -73,6 +73,36 @@ do { \
#define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */
+#define BNAD_DROP_AND_RETURN(_counter) \
+{ \
+ dev_kfree_skb(skb); \
+ BNAD_UPDATE_CTR(bnad, _counter); \
+ return NETDEV_TX_OK; \
+}
+
+#define BNAD_DROP_AND_RETURN_IF(_condition, _counter) \
+if (unlikely(_condition)) { \
+ BNAD_DROP_AND_RETURN(_counter); \
+}
+
+#define BNAD_PCI_UNMAP_SKB(_pdev, _array, _index, _depth, _skb, _frag) \
+{ \
+ int j; \
+ (_array)[_index].skb = NULL; \
+ dma_unmap_single(_pdev, dma_unmap_addr(&(_array)[_index], dma_addr), \
+ skb_headlen(_skb), DMA_TO_DEVICE); \
+ dma_unmap_addr_set(&(_array)[_index], dma_addr, 0); \
+ BNA_QE_INDX_ADD(_index, 1, _depth); \
+ for (j = 0; j < (_frag); j++) { \
+ prefetch(&(_array)[(_index) + 1]); \
+ dma_unmap_page(_pdev, dma_unmap_addr(&(_array)[_index], \
+ dma_addr), \
+ skb_shinfo(_skb)->frags[j].size, DMA_TO_DEVICE); \
+ dma_unmap_addr_set(&(_array)[_index], dma_addr, 0); \
+ BNA_QE_INDX_ADD(_index, 1, _depth); \
+ } \
+}
+
/*
* Reinitialize completions in CQ, once Rx is taken down
*/
@@ -168,7 +198,6 @@ bnad_free_txbufs(struct bnad *bnad,
struct bnad_unmap_q *unmap_q = tcb->unmap_q;
struct bnad_skb_unmap *unmap_array;
struct sk_buff *skb;
- int i;
/*
* Just return if TX is stopped. This check is useful
@@ -198,26 +227,10 @@ bnad_free_txbufs(struct bnad *bnad,
sent_bytes += skb->len;
wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags);
- dma_unmap_single(&bnad->pcidev->dev,
- dma_unmap_addr(&unmap_array[unmap_cons],
- dma_addr), skb_headlen(skb),
- DMA_TO_DEVICE);
- dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
- BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
+ BNAD_PCI_UNMAP_SKB(&bnad->pcidev->dev, unmap_array, unmap_cons,
+ unmap_q->q_depth, skb,
+ skb_shinfo(skb)->nr_frags);
- prefetch(&unmap_array[unmap_cons + 1]);
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- prefetch(&unmap_array[unmap_cons + 1]);
-
- dma_unmap_page(&bnad->pcidev->dev,
- dma_unmap_addr(&unmap_array[unmap_cons],
- dma_addr),
- skb_shinfo(skb)->frags[i].size,
- DMA_TO_DEVICE);
- dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
- 0);
- BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
- }
dev_kfree_skb_any(skb);
}
@@ -388,10 +401,9 @@ bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range);
while (to_alloc--) {
- if (!wi_range) {
+ if (!wi_range)
BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent,
wi_range);
- }
skb = netdev_alloc_skb_ip_align(bnad->netdev,
rcb->rxq->buffer_size);
if (unlikely(!skb)) {
@@ -449,13 +461,10 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
- preempt_disable();
-
set_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) {
clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
- preempt_enable();
return 0;
}
@@ -521,15 +530,13 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
(flags & BNA_CQ_EF_L4_CKSUM_OK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb_checksum_none_assert(skb);
+ skb->ip_summed = CHECKSUM_NONE;
rcb->rxq->rx_packets++;
rcb->rxq->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, bnad->netdev);
if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) {
- struct bnad_rx_ctrl *rx_ctrl =
- (struct bnad_rx_ctrl *)ccb->ctrl;
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp,
ntohs(cmpl->vlan_tag), skb);
@@ -539,8 +546,6 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
ntohs(cmpl->vlan_tag));
} else { /* Not VLAN tagged/stripped */
- struct bnad_rx_ctrl *rx_ctrl =
- (struct bnad_rx_ctrl *)ccb->ctrl;
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
napi_gro_receive(&rx_ctrl->napi, skb);
else
@@ -554,7 +559,8 @@ next:
BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
- rx_ctrl->pkts_to_ack += packets;
+ if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
+ bna_ib_ack_disable_irq(ccb->i_dbell, packets);
bnad_refill_rxq(bnad, ccb->rcb[0]);
if (ccb->rcb[1])
@@ -562,43 +568,19 @@ next:
clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
- preempt_enable();
-
return packets;
}
static void
-bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
-{
- if (unlikely(!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
- return;
-
- bna_ib_coalescing_timer_set(ccb->i_dbell, 0);
- bna_ib_ack(ccb->i_dbell, 0);
-}
-
-static void
-bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
-{
- unsigned long flags;
-
- /* Because of polling context */
- spin_lock_irqsave(&bnad->bna_lock, flags);
- bnad_enable_rx_irq_unsafe(ccb);
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
-}
-
-static void
bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb)
{
struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
struct napi_struct *napi = &rx_ctrl->napi;
if (likely(napi_schedule_prep(napi))) {
- bnad_disable_rx_irq(bnad, ccb);
__napi_schedule(napi);
+ rx_ctrl->rx_schedule++;
}
- BNAD_UPDATE_CTR(bnad, netif_rx_schedule);
}
/* MSIX Rx Path Handler */
@@ -606,10 +588,11 @@ static irqreturn_t
bnad_msix_rx(int irq, void *data)
{
struct bna_ccb *ccb = (struct bna_ccb *)data;
- struct bnad *bnad = ccb->bnad;
- if (ccb)
- bnad_netif_rx_schedule_poll(bnad, ccb);
+ if (ccb) {
+ ((struct bnad_rx_ctrl *)(ccb->ctrl))->rx_intr_ctr++;
+ bnad_netif_rx_schedule_poll(ccb->bnad, ccb);
+ }
return IRQ_HANDLED;
}
@@ -1056,8 +1039,6 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
if (!ccb)
continue;
- rx_ctrl->pkts_to_ack += 0;
-
bnad_cq_cmpl_init(bnad, ccb);
for (j = 0; j < BNAD_MAX_RXQ_PER_RXP; j++) {
@@ -1680,27 +1661,30 @@ bnad_napi_poll_rx(struct napi_struct *napi, int budget)
{
struct bnad_rx_ctrl *rx_ctrl =
container_of(napi, struct bnad_rx_ctrl, napi);
- struct bna_ccb *ccb;
- struct bnad *bnad;
+ struct bnad *bnad = rx_ctrl->bnad;
int rcvd = 0;
+ preempt_disable();
- ccb = rx_ctrl->ccb;
-
- bnad = ccb->bnad;
+ rx_ctrl->rx_poll_ctr++;
if (!netif_carrier_ok(bnad->netdev))
goto poll_exit;
- rcvd = bnad_poll_cq(bnad, ccb, budget);
- if (rcvd == budget)
+ rcvd = bnad_poll_cq(bnad, rx_ctrl->ccb, budget);
+ if (rcvd >= budget) {
+ preempt_enable();
return rcvd;
-
+ }
poll_exit:
- napi_complete((napi));
+ napi_complete(napi);
+
+ rx_ctrl->rx_complete++;
- BNAD_UPDATE_CTR(bnad, netif_rx_complete);
+ preempt_enable();
+
+ if (rx_ctrl->ccb)
+ bnad_enable_rx_irq_unsafe(rx_ctrl->ccb);
- bnad_enable_rx_irq(bnad, ccb);
return rcvd;
}
@@ -1729,9 +1713,6 @@ bnad_napi_enable(struct bnad *bnad, u32 rx_id)
for (i = 0; i < bnad->num_rxp_per_rx; i++) {
rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
- netif_napi_add(bnad->netdev, &rx_ctrl->napi,
- bnad_napi_poll_rx, 64);
-
napi_enable(&rx_ctrl->napi);
}
}
@@ -1907,20 +1888,14 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0];
unsigned long flags;
- int dim_timer_del = 0;
if (!rx_info->rx)
return;
- if (0 == rx_id) {
- spin_lock_irqsave(&bnad->bna_lock, flags);
- dim_timer_del = bnad_dim_timer_running(bnad);
- if (dim_timer_del)
- clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags);
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
- if (dim_timer_del)
- del_timer_sync(&bnad->dim_timer);
- }
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (0 == rx_id)
+ bnad_dim_timer_stop(bnad, flags);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
init_completion(&bnad->bnad_completions.rx_comp);
spin_lock_irqsave(&bnad->bna_lock, flags);
@@ -2429,12 +2404,11 @@ bnad_enable_msix(struct bnad *bnad)
spin_lock_irqsave(&bnad->bna_lock, flags);
/* ret = #of vectors that we got */
- bnad_q_num_adjust(bnad, ret, 0);
+ bnad_q_num_adjust(bnad, (ret - BNAD_MAILBOX_MSIX_VECTORS) / 2,
+ (ret - BNAD_MAILBOX_MSIX_VECTORS) / 2);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx)
- + (bnad->num_rx
- * bnad->num_rxp_per_rx) +
+ bnad->msix_num = BNAD_NUM_TXQ + BNAD_NUM_RXP +
BNAD_MAILBOX_MSIX_VECTORS;
if (bnad->msix_num > ret)
@@ -2591,16 +2565,16 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
u32 unmap_prod, wis, wis_used, wi_range;
u32 vectors, vect_id, i, acked;
int err;
+ unsigned int len;
dma_addr_t dma_addr;
struct bna_txq_entry *txqent;
u16 flags;
- if (unlikely
- (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
+ BNAD_DROP_AND_RETURN_IF(skb->len <= ETH_HLEN, tx_skb_too_short);
+ BNAD_DROP_AND_RETURN_IF(skb_headlen(skb) > BFI_TX_MAX_DATA_PER_VECTOR,
+ tx_skb_headlen_too_long);
+ BNAD_DROP_AND_RETURN_IF(skb_headlen(skb) == 0, tx_skb_headlen_zero);
txq_id = skb_get_queue_mapping(skb);
@@ -2611,16 +2585,13 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
* Takes care of the Tx that is scheduled between clearing the flag
* and the netif_stop_all_queue() call.
*/
- if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
+ BNAD_DROP_AND_RETURN_IF(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags),
+ tx_skb_stopping);
vectors = 1 + skb_shinfo(skb)->nr_frags;
- if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
+ BNAD_DROP_AND_RETURN_IF(vectors > BFI_TX_MAX_VECTORS_PER_PKT,
+ tx_skb_max_vectors);
+
wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
acked = 0;
if (unlikely(wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
@@ -2656,8 +2627,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
unmap_prod = unmap_q->producer_index;
- wis_used = 1;
- vect_id = 0;
flags = 0;
txq_prod = tcb->producer_index;
@@ -2665,9 +2634,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
BUG_ON(!(wi_range <= tcb->q_depth));
txqent->hdr.wi.reserved = 0;
txqent->hdr.wi.num_vectors = vectors;
- txqent->hdr.wi.opcode =
- htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO :
- BNA_TXQ_WI_SEND));
if (vlan_tx_tag_present(skb)) {
vlan_tag = (u16) vlan_tx_tag_get(skb);
@@ -2683,62 +2649,74 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
txqent->hdr.wi.vlan_tag = htons(vlan_tag);
if (skb_is_gso(skb)) {
- err = bnad_tso_prepare(bnad, skb);
- if (err) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+ BNAD_DROP_AND_RETURN_IF(skb_is_gso(skb) > netdev->mtu,
+ tx_skb_mss_too_long);
+ if (unlikely((skb_is_gso(skb) + skb_transport_offset(skb) +
+ tcp_hdrlen(skb)) >= skb->len)) {
+ txqent->hdr.wi.opcode =
+ __constant_htons(BNA_TXQ_WI_SEND);
+ txqent->hdr.wi.lso_mss = 0;
+ BNAD_UPDATE_CTR(bnad, tx_skb_tso_too_short);
+ } else {
+ txqent->hdr.wi.opcode =
+ __constant_htons(BNA_TXQ_WI_SEND_LSO);
+ txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb));
}
- txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb));
+
+ err = bnad_tso_prepare(bnad, skb);
+ BNAD_DROP_AND_RETURN_IF(err, tx_skb_tso_prepare);
flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM);
txqent->hdr.wi.l4_hdr_size_n_offset =
htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
(tcp_hdrlen(skb) >> 2,
skb_transport_offset(skb)));
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- u8 proto = 0;
-
+ } else {
+ txqent->hdr.wi.opcode = __constant_htons(BNA_TXQ_WI_SEND);
txqent->hdr.wi.lso_mss = 0;
- if (skb->protocol == htons(ETH_P_IP))
- proto = ip_hdr(skb)->protocol;
- else if (skb->protocol == htons(ETH_P_IPV6)) {
- /* nexthdr may not be TCP immediately. */
- proto = ipv6_hdr(skb)->nexthdr;
- }
- if (proto == IPPROTO_TCP) {
- flags |= BNA_TXQ_WI_CF_TCP_CKSUM;
- txqent->hdr.wi.l4_hdr_size_n_offset =
- htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
- (0, skb_transport_offset(skb)));
-
- BNAD_UPDATE_CTR(bnad, tcpcsum_offload);
+ BNAD_DROP_AND_RETURN_IF(skb->len > (netdev->mtu + ETH_HLEN),
+ tx_skb_non_tso_too_long);
- BUG_ON(!(skb_headlen(skb) >=
- skb_transport_offset(skb) + tcp_hdrlen(skb)));
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ u8 proto = 0;
- } else if (proto == IPPROTO_UDP) {
- flags |= BNA_TXQ_WI_CF_UDP_CKSUM;
- txqent->hdr.wi.l4_hdr_size_n_offset =
- htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
- (0, skb_transport_offset(skb)));
-
- BNAD_UPDATE_CTR(bnad, udpcsum_offload);
-
- BUG_ON(!(skb_headlen(skb) >=
- skb_transport_offset(skb) +
- sizeof(struct udphdr)));
- } else {
- err = skb_checksum_help(skb);
- BNAD_UPDATE_CTR(bnad, csum_help);
- if (err) {
- dev_kfree_skb(skb);
- BNAD_UPDATE_CTR(bnad, csum_help_err);
- return NETDEV_TX_OK;
+ if (skb->protocol == __constant_htons(ETH_P_IP))
+ proto = ip_hdr(skb)->protocol;
+ else if (skb->protocol ==
+ __constant_htons(ETH_P_IPV6)) {
+ /* nexthdr may not be TCP immediately. */
+ proto = ipv6_hdr(skb)->nexthdr;
}
+ if (proto == IPPROTO_TCP) {
+ flags |= BNA_TXQ_WI_CF_TCP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, tcpcsum_offload);
+
+ BNAD_DROP_AND_RETURN_IF(skb_headlen(skb) <
+ skb_transport_offset(skb) +
+ tcp_hdrlen(skb), tx_skb_tcp_hdr);
+
+ } else if (proto == IPPROTO_UDP) {
+ flags |= BNA_TXQ_WI_CF_UDP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, udpcsum_offload);
+ BNAD_DROP_AND_RETURN_IF(skb_headlen(skb) <
+ skb_transport_offset(skb) +
+ sizeof(struct udphdr),
+ tx_skb_udp_hdr);
+
+ } else {
+ BNAD_DROP_AND_RETURN(tx_skb_csum_err);
+ }
+ } else {
+ txqent->hdr.wi.l4_hdr_size_n_offset = 0;
}
- } else {
- txqent->hdr.wi.lso_mss = 0;
- txqent->hdr.wi.l4_hdr_size_n_offset = 0;
}
txqent->hdr.wi.flags = htons(flags);
@@ -2746,20 +2724,36 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
txqent->hdr.wi.frame_length = htonl(skb->len);
unmap_q->unmap_array[unmap_prod].skb = skb;
- BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR));
- txqent->vector[vect_id].length = htons(skb_headlen(skb));
+ len = skb_headlen(skb);
+ txqent->vector[0].length = htons(len);
dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
dma_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
dma_addr);
- BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
+ BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[0].host_addr);
BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+ vect_id = 0;
+ wis_used = 1;
+
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
u16 size = frag->size;
+ if (unlikely(size == 0)) {
+ unmap_prod = unmap_q->producer_index;
+ prefetch(&unmap_q->unmap_array[unmap_prod + 1]);
+
+ BNAD_PCI_UNMAP_SKB(&bnad->pcidev->dev,
+ unmap_q->unmap_array,
+ unmap_prod, unmap_q->q_depth, skb,
+ i);
+ BNAD_DROP_AND_RETURN(tx_skb_frag_zero);
+ }
+
+ len += size;
+
if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
vect_id = 0;
if (--wi_range)
@@ -2770,10 +2764,10 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
wis_used = 0;
BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt,
txqent, wi_range);
- BUG_ON(!(wi_range <= tcb->q_depth));
}
wis_used++;
- txqent->hdr.wi_ext.opcode = htons(BNA_TXQ_WI_EXTENSION);
+ txqent->hdr.wi_ext.opcode =
+ __constant_htons(BNA_TXQ_WI_EXTENSION);
}
BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR));
@@ -2786,6 +2780,16 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
}
+ if (unlikely(len != skb->len)) {
+ unmap_prod = unmap_q->producer_index;
+ prefetch(&unmap_q->unmap_array[unmap_prod + 1]);
+
+ BNAD_PCI_UNMAP_SKB(&bnad->pcidev->dev, unmap_q->unmap_array,
+ unmap_prod, unmap_q->q_depth, skb,
+ skb_shinfo(skb)->nr_frags);
+ BNAD_DROP_AND_RETURN(tx_skb_len_mismatch);
+ }
+
unmap_q->producer_index = unmap_prod;
BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth);
tcb->producer_index = txq_prod;
@@ -2796,6 +2800,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
bna_txq_prod_indx_doorbell(tcb);
+ smp_mb();
if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
tasklet_schedule(&bnad->tx_free_tasklet);
@@ -2906,6 +2911,9 @@ bnad_set_rx_mode(struct net_device *netdev)
}
}
+ if (bnad->rx_info[0].rx == NULL)
+ goto unlock;
+
bna_rx_mode_set(bnad->rx_info[0].rx, new_mask, valid_mask, NULL);
if (!netdev_mc_empty(netdev)) {
@@ -3067,12 +3075,9 @@ bnad_netpoll(struct net_device *netdev)
continue;
for (j = 0; j < bnad->num_rxp_per_rx; j++) {
rx_ctrl = &rx_info->rx_ctrl[j];
- if (rx_ctrl->ccb) {
- bnad_disable_rx_irq(bnad,
- rx_ctrl->ccb);
+ if (rx_ctrl->ccb)
bnad_netif_rx_schedule_poll(bnad,
rx_ctrl->ccb);
- }
}
}
}
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index 7f0648d..02c6342 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -54,7 +54,11 @@ struct bnad_rx_ctrl {
struct bnad *bnad;
unsigned long flags;
struct napi_struct napi;
- u16 pkts_to_ack;
+ u64 rx_intr_ctr;
+ u64 rx_poll_ctr;
+ u64 rx_schedule;
+ u64 rx_keep_poll;
+ u64 rx_complete;
};
#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC
@@ -150,6 +154,20 @@ struct bnad_drv_stats {
u64 udpcsum_offload;
u64 csum_help;
u64 csum_help_err;
+ u64 tx_skb_too_short;
+ u64 tx_skb_stopping;
+ u64 tx_skb_max_vectors;
+ u64 tx_skb_mss_too_long;
+ u64 tx_skb_tso_too_short;
+ u64 tx_skb_tso_prepare;
+ u64 tx_skb_non_tso_too_long;
+ u64 tx_skb_tcp_hdr;
+ u64 tx_skb_udp_hdr;
+ u64 tx_skb_csum_err;
+ u64 tx_skb_headlen_too_long;
+ u64 tx_skb_headlen_zero;
+ u64 tx_skb_frag_zero;
+ u64 tx_skb_len_mismatch;
u64 hw_stats_updates;
u64 netif_rx_schedule;
@@ -357,7 +375,7 @@ extern void bnad_netdev_hwstats_fill(struct bnad *bnad,
#define bnad_enable_rx_irq_unsafe(_ccb) \
{ \
- if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) {\
+ if (likely(test_bit(BNAD_RXQ_STARTED, &(_ccb)->rcb[0]->flags))) {\
bna_ib_coalescing_timer_set((_ccb)->i_dbell, \
(_ccb)->rx_coalescing_timeo); \
bna_ib_ack((_ccb)->i_dbell, 0); \
@@ -367,5 +385,19 @@ extern void bnad_netdev_hwstats_fill(struct bnad *bnad,
#define bnad_dim_timer_running(_bnad) \
(((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) && \
(test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags))))
+#define bnad_dim_timer_stop(_bnad, _flags) \
+do { \
+ int to_del = 0; \
+ \
+ if ((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED && \
+ test_bit(BNAD_RF_DIM_TIMER_RUNNING, &(_bnad)->run_flags)) {\
+ clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &(_bnad)->run_flags);\
+ to_del = 1; \
+ } \
+ spin_unlock_irqrestore(&(_bnad)->bna_lock, (_flags)); \
+ if (to_del) \
+ del_timer_sync(&(_bnad)->dim_timer); \
+ spin_lock_irqsave(&(_bnad)->bna_lock, (_flags));\
+} while (0)
#endif /* __BNAD_H__ */
--
1.7.1
^ permalink raw reply related
* [PATCH 38/45] bna: HW Error Counter Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Heartbeat failure counter is not incrementing under some scenarios.
Update hbfails and hb_count stats during hwerror event.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 1 +
drivers/net/bna/bfa_ioc.c | 3 +++
drivers/net/bna/bfa_ioc.h | 2 ++
3 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index ebe5e6c..9fe2623 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -155,6 +155,7 @@ struct bfa_ioc_drv_stats {
u32 enable_reqs;
u32 disable_replies;
u32 enable_replies;
+ u32 rsvd;
};
/**
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 6e17abd..e612ca4 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -2217,6 +2217,8 @@ bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
void
bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
{
+ bfa_ioc_stats(ioc, ioc_hbfails);
+ bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
bfa_fsm_send_event(ioc, IOC_E_HWERROR);
}
@@ -2448,6 +2450,7 @@ bfa_ioc_recover(struct bfa_ioc *ioc)
{
pr_crit("Heart Beat of IOC has failed\n");
bfa_ioc_stats(ioc, ioc_hbfails);
+ bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
}
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index 9ae201a..5b6cbbe 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -252,6 +252,8 @@ struct bfa_ioc_hwif {
BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
+#define bfa_ioc_stats_hb_count(_ioc, _hb_count) \
+ ((_ioc)->stats.hb_count = (_hb_count))
#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
#define BFA_IOC_FW_SMEM_SIZE(__ioc) \
((bfa_ioc_asic_gen(__ioc) == BFI_ASIC_GEN_CB) \
--
1.7.1
^ permalink raw reply related
* [PATCH 37/45] bna: Adpater and Port Mode Settings
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Cache the port mode (active and configured) and capability info in
bfa_ioc_attr eliminating need to go to fw. This info will be initialize
to their default value during pci init time, and will be update during
ioc enable reply time and port mode change reply time.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 25 +++++++++++++++++++++++--
drivers/net/bna/bfa_ioc.c | 35 ++++++++++++++++++++++++++++++++++-
drivers/net/bna/bfa_ioc.h | 3 +++
drivers/net/bna/bfi.h | 6 ++++--
4 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index 3e5d096..ebe5e6c 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -180,8 +180,23 @@ struct bfa_ioc_attr {
struct bfa_adapter_attr adapter_attr; /*!< HBA attributes */
struct bfa_ioc_driver_attr driver_attr; /*!< driver attr */
struct bfa_ioc_pci_attr pci_attr;
- u8 port_id; /*!< port number */
- u8 rsvd[7]; /*!< 64bit align */
+ u8 port_id; /*!< port number */
+ u8 port_mode; /*!< enum bfa_mode */
+ u8 cap_bm; /*!< capability */
+ u8 port_mode_cfg; /*!< enum bfa_mode */
+ u8 rsvd[4]; /*!< 64bit align */
+};
+
+/**
+ * Adapter capability mask definition
+ */
+enum {
+ BFA_CM_HBA = 0x01,
+ BFA_CM_CNA = 0x02,
+ BFA_CM_NIC = 0x04,
+ BFA_CM_FC16G = 0x08,
+ BFA_CM_SRIOV = 0x10,
+ BFA_CM_MEZZ = 0x20,
};
/**
@@ -271,4 +286,10 @@ enum {
BFA_PCI_CT2_SSID_FC = 0x24,
};
+enum bfa_mode {
+ BFA_MODE_HBA = 1,
+ BFA_MODE_CNA = 2,
+ BFA_MODE_NIC = 3
+};
+
#endif /* __BFA_DEFS_H__ */
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index d35b91b..6e17abd 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -1706,6 +1706,20 @@ bfa_ioc_reset(struct bfa_ioc *ioc, bool force)
}
/**
+ * BFA ioc enable reply by firmware
+ */
+static void
+bfa_ioc_enable_reply(struct bfa_ioc *ioc, enum bfa_mode port_mode,
+ u8 cap_bm)
+{
+ struct bfa_iocpf *iocpf = &ioc->iocpf;
+
+ ioc->port_mode = ioc->port_mode_cfg = port_mode;
+ ioc->ad_cap_bm = cap_bm;
+ bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
+}
+
+/**
* @brief
* Update BFA configuration from firmware configuration.
*/
@@ -1937,7 +1951,9 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
break;
case BFI_IOC_I2H_ENABLE_REPLY:
- bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
+ bfa_ioc_enable_reply(ioc,
+ (enum bfa_mode)msg->fw_event.port_mode,
+ (enum bfa_mode)msg->fw_event.cap_bm);
break;
case BFI_IOC_I2H_DISABLE_REPLY:
@@ -2012,6 +2028,8 @@ bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
ioc->asic_gen = BFI_ASIC_GEN_CT;
ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
ioc->asic_mode = BFI_ASIC_MODE_ETH;
+ ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
+ ioc->ad_cap_bm = BFA_CM_CNA;
break;
case BFA_PCI_DEVICE_ID_CT2:
@@ -2020,9 +2038,20 @@ bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
ioc->asic_mode = BFI_ASIC_MODE_FC16;
ioc->fcmode = true;
+ ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
+ ioc->ad_cap_bm = BFA_CM_HBA;
} else {
ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
ioc->asic_mode = BFI_ASIC_MODE_ETH;
+ if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
+ ioc->port_mode =
+ ioc->port_mode_cfg = BFA_MODE_CNA;
+ ioc->ad_cap_bm = BFA_CM_CNA;
+ } else {
+ ioc->port_mode =
+ ioc->port_mode_cfg = BFA_MODE_NIC;
+ ioc->ad_cap_bm = BFA_CM_NIC;
+ }
}
break;
@@ -2382,6 +2411,10 @@ bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr)
ioc_attr->state = bfa_ioc_get_state(ioc);
ioc_attr->port_id = ioc->port_id;
+ ioc_attr->port_mode = ioc->port_mode;
+
+ ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
+ ioc_attr->cap_bm = ioc->ad_cap_bm;
ioc_attr->ioc_type = bfa_nw_ioc_get_type(ioc);
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index 0f7dba1..9ae201a 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -208,6 +208,9 @@ struct bfa_ioc {
enum bfi_asic_mode asic_mode;
enum bfi_port_mode port0_mode;
enum bfi_port_mode port1_mode;
+ enum bfa_mode port_mode;
+ u8 ad_cap_bm; /*!< adapter cap bit mask */
+ u8 port_mode_cfg; /*!< config port mode */
};
struct bfa_ioc_hwif {
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
index d422857..c534318 100644
--- a/drivers/net/bna/bfi.h
+++ b/drivers/net/bna/bfi.h
@@ -398,9 +398,11 @@ struct bfi_ioc_ctrl_req {
* BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
*/
struct bfi_ioc_ctrl_reply {
- struct bfi_mhdr mh; /*!< Common msg header */
+ struct bfi_mhdr mh; /*!< Common msg header */
u8 status; /*!< enable/disable status */
- u8 rsvd[3];
+ u8 port_mode; /*!< bfa_mode */
+ u8 cap_bm; /*!< capability bit mask */
+ u8 rsvd;
};
#define BFI_IOC_MSGSZ 8
--
1.7.1
^ permalink raw reply related
* [PATCH 1/4] neigh: Pass neighbour entry to output ops.
From: David Miller @ 2011-07-18 8:25 UTC (permalink / raw)
To: netdev
This will get us closer to being able to do "neigh stuff"
completely independent of the underlying dst_entry for
protocols (ipv4/ipv6) that wish to do so.
We will also be able to make dst entries neigh-less.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/neighbour.h | 19 ++++++++++---------
net/atm/clip.c | 4 ++--
net/bridge/br_netfilter.c | 4 ++--
net/core/neighbour.c | 25 ++++++++++++++-----------
net/decnet/dn_neigh.c | 18 ++++++------------
net/decnet/dn_route.c | 13 ++++++++++---
net/ipv4/arp.c | 6 +++---
net/ipv6/ndisc.c | 6 +++---
8 files changed, 50 insertions(+), 45 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 334e92f..4ba8521 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -109,7 +109,7 @@ struct neighbour {
seqlock_t ha_lock;
unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
struct hh_cache hh;
- int (*output)(struct sk_buff *skb);
+ int (*output)(struct neighbour *, struct sk_buff *);
const struct neigh_ops *ops;
struct rcu_head rcu;
struct net_device *dev;
@@ -118,10 +118,10 @@ struct neighbour {
struct neigh_ops {
int family;
- void (*solicit)(struct neighbour *, struct sk_buff*);
- void (*error_report)(struct neighbour *, struct sk_buff*);
- int (*output)(struct sk_buff*);
- int (*connected_output)(struct sk_buff*);
+ void (*solicit)(struct neighbour *, struct sk_buff *);
+ void (*error_report)(struct neighbour *, struct sk_buff *);
+ int (*output)(struct neighbour *, struct sk_buff *);
+ int (*connected_output)(struct neighbour *, struct sk_buff *);
};
struct pneigh_entry {
@@ -203,9 +203,10 @@ extern int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
u32 flags);
extern void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
extern int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
-extern int neigh_resolve_output(struct sk_buff *skb);
-extern int neigh_connected_output(struct sk_buff *skb);
-extern int neigh_compat_output(struct sk_buff *skb);
+extern int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb);
+extern int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb);
+extern int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb);
+extern int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb);
extern struct neighbour *neigh_event_ns(struct neigh_table *tbl,
u8 *lladdr, void *saddr,
struct net_device *dev);
@@ -348,7 +349,7 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb)
if ((n->nud_state & NUD_CONNECTED) && hh->hh_len)
return neigh_hh_output(hh, skb);
else
- return n->output(skb);
+ return n->output(n, skb);
}
static inline struct neighbour *
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 40d7368..c6cd531 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -271,8 +271,8 @@ static const struct neigh_ops clip_neigh_ops = {
.family = AF_INET,
.solicit = clip_neigh_solicit,
.error_report = clip_neigh_error,
- .output = dev_queue_xmit,
- .connected_output = dev_queue_xmit,
+ .output = neigh_direct_output,
+ .connected_output = neigh_direct_output,
};
static int clip_constructor(struct neighbour *neigh)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 75ee421..1fe43fd 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -355,14 +355,14 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
neigh_hh_bridge(&neigh->hh, skb);
skb->dev = nf_bridge->physindev;
return br_handle_frame_finish(skb);
- } else if (dst->neighbour) {
+ } else {
/* the neighbour function below overwrites the complete
* MAC header, so we save the Ethernet source address and
* protocol number. */
skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
/* tell br_dev_xmit to continue with forwarding */
nf_bridge->mask |= BRNF_BRIDGED_DNAT;
- return dst->neighbour->output(skb);
+ return neigh->output(neigh, skb);
}
free_skb:
kfree_skb(skb);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b031cf6..cefb8e5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -98,7 +98,7 @@ static const struct file_operations neigh_stat_seq_fops;
static DEFINE_RWLOCK(neigh_tbl_lock);
-static int neigh_blackhole(struct sk_buff *skb)
+static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb)
{
kfree_skb(skb);
return -ENETDOWN;
@@ -1158,7 +1158,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
/* On shaper/eql skb->dst->neighbour != neigh :( */
if (skb_dst(skb) && skb_dst(skb)->neighbour)
n1 = skb_dst(skb)->neighbour;
- n1->output(skb);
+ n1->output(n1, skb);
write_lock_bh(&neigh->lock);
}
skb_queue_purge(&neigh->arp_queue);
@@ -1214,7 +1214,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst)
* but resolution is not made yet.
*/
-int neigh_compat_output(struct sk_buff *skb)
+int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
@@ -1231,13 +1231,12 @@ EXPORT_SYMBOL(neigh_compat_output);
/* Slow and careful. */
-int neigh_resolve_output(struct sk_buff *skb)
+int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct neighbour *neigh;
int rc = 0;
- if (!dst || !(neigh = dst->neighbour))
+ if (!dst)
goto discard;
__skb_pull(skb, skb_network_offset(skb));
@@ -1265,7 +1264,7 @@ out:
return rc;
discard:
NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n",
- dst, dst ? dst->neighbour : NULL);
+ dst, neigh);
out_kfree_skb:
rc = -EINVAL;
kfree_skb(skb);
@@ -1275,13 +1274,11 @@ EXPORT_SYMBOL(neigh_resolve_output);
/* As fast as possible without hh cache */
-int neigh_connected_output(struct sk_buff *skb)
+int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb)
{
- int err;
- struct dst_entry *dst = skb_dst(skb);
- struct neighbour *neigh = dst->neighbour;
struct net_device *dev = neigh->dev;
unsigned int seq;
+ int err;
__skb_pull(skb, skb_network_offset(skb));
@@ -1301,6 +1298,12 @@ int neigh_connected_output(struct sk_buff *skb)
}
EXPORT_SYMBOL(neigh_connected_output);
+int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb)
+{
+ return dev_queue_xmit(skb);
+}
+EXPORT_SYMBOL(neigh_direct_output);
+
static void neigh_proxy_process(unsigned long arg)
{
struct neigh_table *tbl = (struct neigh_table *)arg;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 84fee8a..5d61e89 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -51,9 +51,9 @@
static int dn_neigh_construct(struct neighbour *);
static void dn_long_error_report(struct neighbour *, struct sk_buff *);
static void dn_short_error_report(struct neighbour *, struct sk_buff *);
-static int dn_long_output(struct sk_buff *);
-static int dn_short_output(struct sk_buff *);
-static int dn_phase3_output(struct sk_buff *);
+static int dn_long_output(struct neighbour *, struct sk_buff *);
+static int dn_short_output(struct neighbour *, struct sk_buff *);
+static int dn_phase3_output(struct neighbour *, struct sk_buff *);
/*
@@ -218,10 +218,8 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
return -EINVAL;
}
-static int dn_long_output(struct sk_buff *skb)
+static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb)
{
- struct dst_entry *dst = skb_dst(skb);
- struct neighbour *neigh = dst->neighbour;
struct net_device *dev = neigh->dev;
int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
unsigned char *data;
@@ -265,10 +263,8 @@ static int dn_long_output(struct sk_buff *skb)
neigh->dev, dn_neigh_output_packet);
}
-static int dn_short_output(struct sk_buff *skb)
+static int dn_short_output(struct neighbour *neigh, struct sk_buff *skb)
{
- struct dst_entry *dst = skb_dst(skb);
- struct neighbour *neigh = dst->neighbour;
struct net_device *dev = neigh->dev;
int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
struct dn_short_packet *sp;
@@ -309,10 +305,8 @@ static int dn_short_output(struct sk_buff *skb)
* Phase 3 output is the same is short output, execpt that
* it clears the area bits before transmission.
*/
-static int dn_phase3_output(struct sk_buff *skb)
+static int dn_phase3_output(struct neighbour *neigh, struct sk_buff *skb)
{
- struct dst_entry *dst = skb_dst(skb);
- struct neighbour *neigh = dst->neighbour;
struct net_device *dev = neigh->dev;
int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
struct dn_short_packet *sp;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index fceb86c..3b6400d 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -705,6 +705,14 @@ out:
return NET_RX_DROP;
}
+static int dn_to_neigh_output(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb_dst(skb);
+ struct neighbour *n = dst->neighbour;
+
+ return n->output(n, skb);
+}
+
static int dn_output(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
@@ -733,7 +741,7 @@ static int dn_output(struct sk_buff *skb)
cb->hops = 0;
return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT, skb, NULL, dev,
- neigh->output);
+ dn_to_neigh_output);
error:
if (net_ratelimit())
@@ -750,7 +758,6 @@ static int dn_forward(struct sk_buff *skb)
struct dst_entry *dst = skb_dst(skb);
struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr);
struct dn_route *rt;
- struct neighbour *neigh = dst->neighbour;
int header_len;
#ifdef CONFIG_NETFILTER
struct net_device *dev = skb->dev;
@@ -783,7 +790,7 @@ static int dn_forward(struct sk_buff *skb)
cb->rt_flags |= DN_RT_F_IE;
return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD, skb, dev, skb->dev,
- neigh->output);
+ dn_to_neigh_output);
drop:
kfree_skb(skb);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 8a21403..96a164a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -150,8 +150,8 @@ static const struct neigh_ops arp_hh_ops = {
static const struct neigh_ops arp_direct_ops = {
.family = AF_INET,
- .output = dev_queue_xmit,
- .connected_output = dev_queue_xmit,
+ .output = neigh_direct_output,
+ .connected_output = neigh_direct_output,
};
static const struct neigh_ops arp_broken_ops = {
@@ -250,7 +250,7 @@ static int arp_constructor(struct neighbour *neigh)
if (!dev->header_ops) {
neigh->nud_state = NUD_NOARP;
neigh->ops = &arp_direct_ops;
- neigh->output = dev_queue_xmit;
+ neigh->output = neigh_direct_output;
} else {
/* Good devices (checked by reading texts, but only Ethernet is
tested)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 482b970..e08ce55 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -120,8 +120,8 @@ static const struct neigh_ops ndisc_hh_ops = {
static const struct neigh_ops ndisc_direct_ops = {
.family = AF_INET6,
- .output = dev_queue_xmit,
- .connected_output = dev_queue_xmit,
+ .output = neigh_direct_output,
+ .connected_output = neigh_direct_output,
};
struct neigh_table nd_tbl = {
@@ -386,7 +386,7 @@ static int ndisc_constructor(struct neighbour *neigh)
if (!dev->header_ops) {
neigh->nud_state = NUD_NOARP;
neigh->ops = &ndisc_direct_ops;
- neigh->output = dev_queue_xmit;
+ neigh->output = neigh_direct_output;
} else {
if (is_multicast) {
neigh->nud_state = NUD_NOARP;
--
1.7.6
^ permalink raw reply related
* [PATCH 36/45] bna: Data Path and API Changes
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Data path change:
Accumulate the acks in the driver upto ~32K or 15 bits (+ 64, at the max),
if poosible and then ack, otherwise ack and enable interrupts when no more
packets are there to be processed.
- Currently, mailbox MSIX vector is part of bna resources. Due to this, the
MSIX vectors need to be allocated before bna_init(). Bfa_ioc_pci_init()
called from bna_ioceth_init() called from bna_init() has MSIX vector setup.
However, bfa_ioc_pci_init() needs to be called before enabling msix &
allocating MSIX vector. Due to this, bna_init() needs to be called before
enabling & allocating MSIX vectors. Hence, removing mailbox MSIX vector as
a resource requirement for bna. Mailbox MSIX vector need not be explicitly
passed for bna_init(), since mbox MSIX vector is always going to be 0.
- Bnad_mbox_irq_alloc/free() function changes - removal of bna_intr_info
- Bnad_res_alloc/free() function changes - removal of calling
bnad_mbox_irq_alloc/free()
- Calling bnad_enable_msix(), bnad_mbox_irq_alloc() after bna_init()
- Calling bnad_mbox_irq_free() just before bnad_disable_msix()
- IOC timer : use iocpf_timer to ioc_timer.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 46 +++++++++++-------
drivers/net/bna/bfi.h | 2 +-
drivers/net/bna/bnad.c | 115 +++++++++++++++++----------------------------
drivers/net/bna/bnad.h | 1 +
drivers/net/bna/cna.h | 4 +-
5 files changed, 75 insertions(+), 93 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 940c94a..d35b91b 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -85,6 +85,7 @@ static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_param);
static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
+static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr);
static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
char *serial_num);
static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc,
@@ -754,7 +755,7 @@ bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
bfa_ioc_pf_fwmismatch(iocpf->ioc);
iocpf->fw_mismatch_notified = true;
- mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ mod_timer(&iocpf->ioc->ioc_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
}
@@ -772,13 +773,13 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
bfa_ioc_pf_disabled(ioc);
break;
case IOCPF_E_STOP:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
break;
@@ -859,7 +860,7 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_ioc_sync_leave(ioc);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
@@ -873,7 +874,7 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
{
- mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ mod_timer(&iocpf->ioc->ioc_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
/**
* Enable Interrupts before sending fw IOC ENABLE cmd.
@@ -893,13 +894,13 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_ENABLE:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
break;
case IOCPF_E_INITFAIL:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
/*
* !!! fall through !!!
*/
@@ -911,7 +912,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
break;
case IOCPF_E_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
@@ -951,7 +952,7 @@ bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf)
{
- mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
+ mod_timer(&iocpf->ioc->ioc_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
bfa_ioc_send_disable(iocpf->ioc);
}
@@ -966,12 +967,12 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_DISABLE:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
case IOCPF_E_FAIL:
- del_timer(&ioc->iocpf_timer);
+ del_timer(&ioc->ioc_timer);
/*
* !!! fall through !!!
*/
@@ -1245,13 +1246,13 @@ bfa_nw_ioc_sem_get(void __iomem *sem_reg)
r32 = readl(sem_reg);
- while (r32 && (cnt < BFA_SEM_SPINCNT)) {
+ while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
cnt++;
udelay(2);
r32 = readl(sem_reg);
}
- if (r32 == 0)
+ if (!(r32 & 1))
return true;
BUG_ON(!(cnt < BFA_SEM_SPINCNT));
@@ -1396,12 +1397,13 @@ bfa_ioc_lpu_stop(struct bfa_ioc *ioc)
void
bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
{
- u32 pgnum;
+ u32 pgnum, pgoff;
u32 loff = 0;
int i;
u32 *fwsig = (u32 *) fwhdr;
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32));
@@ -1479,11 +1481,12 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
- boot_env = BFI_FWBOOT_ENV_OS;
-
if (force)
ioc_fwstate = BFI_IOC_UNINIT;
+ boot_env = BFI_FWBOOT_ENV_OS;
+
+
/**
* check if firmware is valid
*/
@@ -1636,7 +1639,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_env)
{
u32 *fwimg;
- u32 pgnum;
+ u32 pgnum, pgoff;
u32 loff = 0;
u32 chunkno = 0;
u32 i;
@@ -1650,6 +1653,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
writel(pgnum, ioc->ioc_regs.host_page_num_fn);
@@ -1685,7 +1689,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
/*
* Set boot type, env and device mode at the end.
*/
- asicmode = BFI_FWBOOT_ASICMODE(ioc->asic_gen, ioc->asic_mode,
+ asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
ioc->port0_mode, ioc->port1_mode);
writel(asicmode, ((ioc->ioc_regs.smem_page_start)
+ BFI_FWBOOT_DEVMODE_OFF));
@@ -2086,6 +2090,12 @@ bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr)
return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
}
+static u32
+bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr)
+{
+ return PSS_SMEM_PGOFF(fmaddr);
+}
+
/**
* Register mailbox message handler function, to be called by common modules
*/
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
index 8d238a7..d422857 100644
--- a/drivers/net/bna/bfi.h
+++ b/drivers/net/bna/bfi.h
@@ -307,7 +307,7 @@ struct bfi_ioc_image_hdr {
#define BFI_FWBOOT_DEVMODE_OFF 4
#define BFI_FWBOOT_TYPE_OFF 8
#define BFI_FWBOOT_ENV_OFF 12
-#define BFI_FWBOOT_ASICMODE(__asic_gen, __asic_mode, __p0_mode, __p1_mode) \
+#define BFI_FWBOOT_DEVMODE(__asic_gen, __asic_mode, __p0_mode, __p1_mode) \
(((u32)(__asic_gen)) << 24 | \
((u32)(__asic_mode)) << 16 | \
((u32)(__p0_mode)) << 8 | \
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 3f9ddbf..f6b7401 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -554,8 +554,8 @@ next:
BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
- if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
- bna_ib_ack(ccb->i_dbell, packets);
+ rx_ctrl->pkts_to_ack += packets;
+
bnad_refill_rxq(bnad, ccb->rcb[0]);
if (ccb->rcb[1])
bnad_refill_rxq(bnad, ccb->rcb[1]);
@@ -1056,6 +1056,8 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
if (!ccb)
continue;
+ rx_ctrl->pkts_to_ack += 0;
+
bnad_cq_cmpl_init(bnad, ccb);
for (j = 0; j < BNAD_MAX_RXQ_PER_RXP; j++) {
@@ -1195,23 +1197,17 @@ err_return:
/* Free IRQ for Mailbox */
static void
-bnad_mbox_irq_free(struct bnad *bnad,
- struct bna_intr_info *intr_info)
+bnad_mbox_irq_free(struct bnad *bnad)
{
int irq;
unsigned long flags;
- if (intr_info->idl == NULL)
- return;
-
spin_lock_irqsave(&bnad->bna_lock, flags);
bnad_disable_mbox_irq(bnad);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
irq = BNAD_GET_MBOX_IRQ(bnad);
free_irq(irq, bnad);
-
- kfree(intr_info->idl);
}
/*
@@ -1220,32 +1216,22 @@ bnad_mbox_irq_free(struct bnad *bnad,
* from bna
*/
static int
-bnad_mbox_irq_alloc(struct bnad *bnad,
- struct bna_intr_info *intr_info)
+bnad_mbox_irq_alloc(struct bnad *bnad)
{
int err = 0;
unsigned long irq_flags, flags;
u32 irq;
irq_handler_t irq_handler;
- /* Mbox should use only 1 vector */
-
- intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL);
- if (!intr_info->idl)
- return -ENOMEM;
-
spin_lock_irqsave(&bnad->bna_lock, flags);
if (bnad->cfg_flags & BNAD_CF_MSIX) {
irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
irq = bnad->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector;
irq_flags = 0;
- intr_info->intr_type = BNA_INTR_T_MSIX;
- intr_info->idl[0].vector = BNAD_MAILBOX_MSIX_INDEX;
} else {
irq_handler = (irq_handler_t)bnad_isr;
irq = bnad->pcidev->irq;
irq_flags = IRQF_SHARED;
- intr_info->intr_type = BNA_INTR_T_INTX;
}
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1262,11 +1248,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
err = request_irq(irq, irq_handler, irq_flags,
bnad->mbox_irq_name, bnad);
- if (err) {
- kfree(intr_info->idl);
- intr_info->idl = NULL;
- }
-
return err;
}
@@ -1723,6 +1704,21 @@ poll_exit:
return rcvd;
}
+#define BNAD_NAPI_POLL_QUOTA 64
+static void
+bnad_napi_init(struct bnad *bnad, u32 rx_id)
+{
+ struct bnad_rx_ctrl *rx_ctrl;
+ int i;
+
+ /* Initialize & enable NAPI */
+ for (i = 0; i < bnad->num_rxp_per_rx; i++) {
+ rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
+ netif_napi_add(bnad->netdev, &rx_ctrl->napi,
+ bnad_napi_poll_rx, BNAD_NAPI_POLL_QUOTA);
+ }
+}
+
static void
bnad_napi_enable(struct bnad *bnad, u32 rx_id)
{
@@ -1786,29 +1782,6 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
bnad_tx_res_free(bnad, res_info);
}
-/*
- * Sets up bnad->num_tx depending on the current value (already
- * adjusted based on MSIX vectors available and ETS support in
- * the chip
- */
-static void
-bnad_num_txq_set(struct bnad *bnad)
-{
- struct bna *bna = &bnad->bna;
- struct bna_attr attr;
- unsigned long flags;
-
- spin_lock_irqsave(&bnad->bna_lock, flags);
- attr = bna->ioceth.attr;
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
-
- if (attr.max_ets_groups < BFI_TX_MAX_PRIO)
- bnad->num_txq_per_tx = 1;
- else
- bnad->num_txq_per_tx = min((u32)attr.max_ets_groups,
- (u32)bnad->num_txq_per_tx);
-}
-
/* Should be held with conf_lock held */
int
bnad_setup_tx(struct bnad *bnad, u32 tx_id)
@@ -1825,8 +1798,6 @@ bnad_setup_tx(struct bnad *bnad, u32 tx_id)
tx_info->tx_id = tx_id;
- bnad_num_txq_set(bnad);
-
/* Initialize the Tx object configuration */
tx_config->num_txq = bnad->num_txq_per_tx;
tx_config->txq_depth = bnad->txq_depth;
@@ -2026,8 +1997,11 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
goto err_return;
rx_info->rx = rx;
- /* Enable NAPI */
- bnad_napi_enable(bnad, rx_id);
+ /*
+ * Init NAPI, so that state is set to NAPI_STATE_SCHED,
+ * so that IRQ handler cannot schedule NAPI at this point.
+ */
+ bnad_napi_init(bnad, rx_id);
/* Register ISR for the Rx object */
if (intr_info->intr_type == BNA_INTR_T_MSIX) {
@@ -2053,6 +2027,9 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
bna_rx_enable(rx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ /* Enable scheduling of NAPI */
+ bnad_napi_enable(bnad, rx_id);
+
return 0;
err_return:
@@ -2397,12 +2374,8 @@ bnad_res_free(struct bnad *bnad, struct bna_res_info *res_info,
{
int i;
- for (i = 0; i < res_val_max; i++) {
- if (res_info[i].res_type == BNA_RES_T_MEM)
- bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
- else
- bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info);
- }
+ for (i = 0; i < res_val_max; i++)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
}
/* Allocates memory and interrupt resources for BNA */
@@ -2413,11 +2386,7 @@ bnad_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
int i, err;
for (i = 0; i < res_val_max; i++) {
- if (res_info[i].res_type == BNA_RES_T_MEM)
- err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
- else
- err = bnad_mbox_irq_alloc(bnad,
- &res_info[i].res_u.intr_info);
+ err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
if (err)
goto err_return;
}
@@ -2637,11 +2606,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
tcb = bnad->tx_info[0].tcb[txq_id];
- if (unlikely(!tcb)) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
unmap_q = tcb->unmap_q;
/*
* Takes care of the Tx that is scheduled between clearing the flag
@@ -3351,8 +3315,6 @@ bnad_pci_probe(struct pci_dev *pdev,
/* Set link to down state */
netif_carrier_off(netdev);
- bnad_enable_msix(bnad);
-
/* Get resource requirement form bna */
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_res_req(&bnad->res_info[0]);
@@ -3377,6 +3339,12 @@ bnad_pci_probe(struct pci_dev *pdev,
bnad->stats.bna_stats = &bna->stats;
+ bnad_enable_msix(bnad);
+ err = bnad_mbox_irq_alloc(bnad);
+ if (err)
+ goto res_free;
+
+
/* Set up timers */
setup_timer(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout,
((unsigned long)bnad));
@@ -3388,7 +3356,7 @@ bnad_pci_probe(struct pci_dev *pdev,
((unsigned long)bnad));
/* Now start the timer before calling IOC */
- mod_timer(&bnad->bna.ioceth.ioc.iocpf_timer,
+ mod_timer(&bnad->bna.ioceth.ioc.ioc_timer,
jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ));
/*
@@ -3455,9 +3423,11 @@ disable_ioceth:
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ bnad_mbox_irq_free(bnad);
+ bnad_disable_msix(bnad);
+res_free:
bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
drv_uninit:
- bnad_disable_msix(bnad);
bnad_uninit(bnad);
pci_uninit:
bnad_pci_uninit(pdev);
@@ -3497,6 +3467,7 @@ bnad_pci_remove(struct pci_dev *pdev)
bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
+ bnad_mbox_irq_free(bnad);
bnad_disable_msix(bnad);
bnad_pci_uninit(pdev);
mutex_unlock(&bnad->conf_mutex);
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index 4f9da1c..7f0648d 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -54,6 +54,7 @@ struct bnad_rx_ctrl {
struct bnad *bnad;
unsigned long flags;
struct napi_struct napi;
+ u16 pkts_to_ack;
};
#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC
diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h
index 50fce15..94005d6 100644
--- a/drivers/net/bna/cna.h
+++ b/drivers/net/bna/cna.h
@@ -34,8 +34,8 @@
#include <linux/list.h>
#define bfa_sm_fault(__event) do { \
- pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \
- __event); \
+ pr_err("SM Assertion failure: %s: %d: event = %d\n", \
+ __FILE__, __LINE__, __event); \
} while (0)
extern char bfa_version[];
--
1.7.1
^ permalink raw reply related
* [PATCH 0/4] More work towards neigh-less dsts.
From: David Miller @ 2011-07-18 8:24 UTC (permalink / raw)
To: netdev
This continues the effort to divorce neighbour from dst_entry as
much as possible.
When we remove the routing cache, route entries will be fully generic
and not specific to any particular keyed destination. Therefore we'll
need to lookup neigh entries dynamically, and quickly, at packet
output time.
To that end, this series:
1) Passes an explicit neighbour to packet out neigh_ops.
2) Abstracts all dst->neighbour behind helpers to ease the
transition process.
3) Adds a new dst_ops entry, ->neigh_lookup(), to provide a transition
scheme for dst->neighbour uses outside of the packet output path.
The next set of patches after this one will deal with all of
the dst_get_neighbour() code paths, converting them over to
dst_neigh_lookup()/neigh_release() sequences.
Then there will be a little bit of fiddling around in decnet since
it's usage of dst->neighbour is still too tight in the packet output
path.
Finally, we can kill dst->neighbour and do RCU neigh lookups in the
packet output paths for all the protocols using the neighbour cache
(ipv4, ipv6, decnet).
^ permalink raw reply
* [PATCH 35/45] bna: Change TxQ Select Logic and Interrupt Handling
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Simplify the TxQ selection logic:
Macro BNAD_TXQ_ID_GET() calls bnad_tx_select_queue(), which returns priority.
While only a few packets during transition could have wrong priority, all
will be associated with a valid non-NULL tcb.
- Add bnad pointer to rx_ctrl structure, so that bnad can be accessed directly
from rx_ctrl in the NAPI poll routines, even if ccb is NULL
- Fix the order of init / uninit in Tx / Rx setup / teardown path:
Kill bnad tx free tasklet ahead of call to bna_tx_destroy().
Call NAPI disable only aftet call to Rx free_irq(). This makes sure Rx
interrupt does not schedule a poll when NAPI is already disabled.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bnad.c | 70 +++++++++++++++++++++++++++++++----------------
drivers/net/bna/bnad.h | 1 +
2 files changed, 47 insertions(+), 24 deletions(-)
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 8ca1b60..3f9ddbf 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -554,16 +554,11 @@ next:
BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
- if (likely(ccb)) {
- if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
- bna_ib_ack(ccb->i_dbell, packets);
- bnad_refill_rxq(bnad, ccb->rcb[0]);
- if (ccb->rcb[1])
- bnad_refill_rxq(bnad, ccb->rcb[1]);
- } else {
- if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
- bna_ib_ack(ccb->i_dbell, 0);
- }
+ if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
+ bna_ib_ack(ccb->i_dbell, packets);
+ bnad_refill_rxq(bnad, ccb->rcb[0]);
+ if (ccb->rcb[1])
+ bnad_refill_rxq(bnad, ccb->rcb[1]);
clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
@@ -613,7 +608,8 @@ bnad_msix_rx(int irq, void *data)
struct bna_ccb *ccb = (struct bna_ccb *)data;
struct bnad *bnad = ccb->bnad;
- bnad_netif_rx_schedule_poll(bnad, ccb);
+ if (ccb)
+ bnad_netif_rx_schedule_poll(bnad, ccb);
return IRQ_HANDLED;
}
@@ -652,6 +648,7 @@ bnad_isr(int irq, void *data)
struct bnad *bnad = (struct bnad *)data;
struct bnad_rx_info *rx_info;
struct bnad_rx_ctrl *rx_ctrl;
+ struct bna_tcb *tcb = NULL;
if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
return IRQ_NONE;
@@ -674,8 +671,11 @@ bnad_isr(int irq, void *data)
/* Process data interrupts */
/* Tx processing */
for (i = 0; i < bnad->num_tx; i++) {
- for (j = 0; j < bnad->num_txq_per_tx; j++)
- bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ tcb = bnad->tx_info[i].tcb[j];
+ if (tcb && test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
+ bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ }
}
/* Rx processing */
for (i = 0; i < bnad->num_rx; i++) {
@@ -1773,6 +1773,9 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
bnad_tx_msix_unregister(bnad, tx_info,
bnad->num_txq_per_tx);
+ if (0 == tx_id)
+ tasklet_kill(&bnad->tx_free_tasklet);
+
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_tx_destroy(tx_info->tx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1780,9 +1783,6 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
tx_info->tx = NULL;
tx_info->tx_id = 0;
- if (0 == tx_id)
- tasklet_kill(&bnad->tx_free_tasklet);
-
bnad_tx_res_free(bnad, res_info);
}
@@ -1918,6 +1918,16 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED;
}
+static void
+bnad_rx_ctrl_init(struct bnad *bnad, u32 rx_id)
+{
+ struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
+ int i;
+
+ for (i = 0; i < bnad->num_rxp_per_rx; i++)
+ rx_info->rx_ctrl[i].bnad = bnad;
+}
+
/* Called with mutex_lock(&bnad->conf_mutex) held */
void
bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
@@ -1941,8 +1951,6 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
del_timer_sync(&bnad->dim_timer);
}
- bnad_napi_disable(bnad, rx_id);
-
init_completion(&bnad->bnad_completions.rx_comp);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled);
@@ -1952,6 +1960,8 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
+ bnad_napi_disable(bnad, rx_id);
+
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_rx_destroy(rx_info->rx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -2005,6 +2015,8 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
if (err)
return err;
+ bnad_rx_ctrl_init(bnad, rx_id);
+
/* Ask BNA to create one Rx object, supplying required resources */
spin_lock_irqsave(&bnad->bna_lock, flags);
rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info,
@@ -2014,6 +2026,9 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
goto err_return;
rx_info->rx = rx;
+ /* Enable NAPI */
+ bnad_napi_enable(bnad, rx_id);
+
/* Register ISR for the Rx object */
if (intr_info->intr_type == BNA_INTR_T_MSIX) {
err = bnad_rx_msix_register(bnad, rx_info, rx_id,
@@ -2022,9 +2037,6 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
goto err_return;
}
- /* Enable NAPI */
- bnad_napi_enable(bnad, rx_id);
-
spin_lock_irqsave(&bnad->bna_lock, flags);
if (0 == rx_id) {
/* Set up Dynamic Interrupt Moderation Vector */
@@ -2602,15 +2614,15 @@ static netdev_tx_t
bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct bnad *bnad = netdev_priv(netdev);
- u32 txq_id = 0;
- struct bna_tcb *tcb = bnad->tx_info[0].tcb[txq_id];
+ struct bna_tcb *tcb = NULL;
+ u32 txq_id;
+ struct bnad_unmap_q *unmap_q;
u16 txq_prod, vlan_tag = 0;
u32 unmap_prod, wis, wis_used, wi_range;
u32 vectors, vect_id, i, acked;
int err;
- struct bnad_unmap_q *unmap_q = tcb->unmap_q;
dma_addr_t dma_addr;
struct bna_txq_entry *txqent;
u16 flags;
@@ -2621,6 +2633,16 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
+ txq_id = skb_get_queue_mapping(skb);
+
+ tcb = bnad->tx_info[0].tcb[txq_id];
+
+ if (unlikely(!tcb)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ unmap_q = tcb->unmap_q;
/*
* Takes care of the Tx that is scheduled between clearing the flag
* and the netif_stop_all_queue() call.
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index 1b87b27..4f9da1c 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -51,6 +51,7 @@
*/
struct bnad_rx_ctrl {
struct bna_ccb *ccb;
+ struct bnad *bnad;
unsigned long flags;
struct napi_struct napi;
};
--
1.7.1
^ permalink raw reply related
* [PATCH 34/45] bna: Add Multiple Tx Queue Support
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Added support for multipe Tx queues with a separate iSCSI Tx queue based
on the default value of iSCSI port number. The feature is supported based
on the underlying hardware and enabled for DCB (CEE) mode only.
- Allocate multiple TxQ resource in netdev
- Implement bnad_tx_select_queue() which enables the correct selection of
TxQ Id (and tcb). This function is called either by the kernel to channel
packets to the right TxQ
- Implement bnad_iscsi_tcb_get() and BNAD_IS_ISCSI_PKT() for iSCSI packet
inspection and retrieval of tcb corresponding to the iSCSI priority.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bna_types.h | 2 +
drivers/net/bna/bnad.c | 146 ++++++++++++++++++++++++++++++++++---------
drivers/net/bna/bnad.h | 9 +++
3 files changed, 127 insertions(+), 30 deletions(-)
diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h
index a4f71c0..7f037db 100644
--- a/drivers/net/bna/bna_types.h
+++ b/drivers/net/bna/bna_types.h
@@ -329,6 +329,7 @@ struct bna_attr {
int num_ucmac;
int num_mcmac;
int max_rit_size;
+ int max_ets_groups;
};
/**
@@ -578,6 +579,7 @@ struct bna_tx_mod {
int iscsi_over_cee;
int iscsi_prio;
int prio_reconfigured;
+ void *prio_indirection[BFI_TX_MAX_PRIO];
u32 rid_mask;
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 2b716ed..8ca1b60 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -194,8 +194,6 @@ bnad_free_txbufs(struct bnad *bnad,
while (wis) {
skb = unmap_array[unmap_cons].skb;
- unmap_array[unmap_cons].skb = NULL;
-
sent_packets++;
sent_bytes += skb->len;
wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags);
@@ -245,7 +243,7 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr)
{
struct bnad *bnad = (struct bnad *)bnad_ptr;
struct bna_tcb *tcb;
- u32 acked = 0;
+ u32 acked = 0, txq_id;
int i, j;
for (i = 0; i < bnad->num_tx; i++) {
@@ -264,14 +262,20 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr)
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
}
+ /*
+ * Check again, because this bit can be set from another
+ * context. This is not lock protected.
+ */
if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED,
&tcb->flags)))
continue;
- if (netif_queue_stopped(bnad->netdev)) {
+ txq_id = tcb->id;
+ if (__netif_subqueue_stopped(bnad->netdev, txq_id)) {
if (acked && netif_carrier_ok(bnad->netdev) &&
BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
BNAD_NETIF_WAKE_THRESHOLD) {
- netif_wake_queue(bnad->netdev);
+ netif_wake_subqueue(bnad->netdev,
+ txq_id);
/* TODO */
/* Counters for individual TxQs? */
BNAD_UPDATE_CTR(bnad,
@@ -286,19 +290,21 @@ static u32
bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
{
struct net_device *netdev = bnad->netdev;
- u32 sent = 0;
+ u32 sent = 0, txq_id;
if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
return 0;
sent = bnad_free_txbufs(bnad, tcb);
if (sent) {
- if (netif_queue_stopped(netdev) &&
+ txq_id = tcb->id;
+
+ if (__netif_subqueue_stopped(netdev, txq_id) &&
netif_carrier_ok(netdev) &&
BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
BNAD_NETIF_WAKE_THRESHOLD) {
if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) {
- netif_wake_queue(netdev);
+ netif_wake_subqueue(netdev, txq_id);
BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
}
}
@@ -850,7 +856,9 @@ bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb)
(struct bnad_tx_info *)tcb->txq->tx->priv;
struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+ tcb->priv = tcb;
tx_info->tcb[tcb->id] = tcb;
+
unmap_q->producer_index = 0;
unmap_q->consumer_index = 0;
unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH;
@@ -875,6 +883,7 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
tx_info->tcb[tcb->id] = NULL;
+ tcb->priv = NULL;
}
static void
@@ -1777,6 +1786,29 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
bnad_tx_res_free(bnad, res_info);
}
+/*
+ * Sets up bnad->num_tx depending on the current value (already
+ * adjusted based on MSIX vectors available and ETS support in
+ * the chip
+ */
+static void
+bnad_num_txq_set(struct bnad *bnad)
+{
+ struct bna *bna = &bnad->bna;
+ struct bna_attr attr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ attr = bna->ioceth.attr;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (attr.max_ets_groups < BFI_TX_MAX_PRIO)
+ bnad->num_txq_per_tx = 1;
+ else
+ bnad->num_txq_per_tx = min((u32)attr.max_ets_groups,
+ (u32)bnad->num_txq_per_tx);
+}
+
/* Should be held with conf_lock held */
int
bnad_setup_tx(struct bnad *bnad, u32 tx_id)
@@ -1793,6 +1825,8 @@ bnad_setup_tx(struct bnad *bnad, u32 tx_id)
tx_info->tx_id = tx_id;
+ bnad_num_txq_set(bnad);
+
/* Initialize the Tx object configuration */
tx_config->num_txq = bnad->num_txq_per_tx;
tx_config->txq_depth = bnad->txq_depth;
@@ -2264,38 +2298,45 @@ bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
static void
bnad_q_num_init(struct bnad *bnad)
{
- int rxps;
+ int rxps = min((u32)num_online_cpus(),
+ (u32)(BNAD_MAX_RXP_PER_RX));
- rxps = min((uint)num_online_cpus(),
- (uint)(BNAD_MAX_RX * BNAD_MAX_RXP_PER_RX));
+ BNA_TO_POWER_OF_2(rxps);
if (!(bnad->cfg_flags & BNAD_CF_MSIX))
rxps = 1; /* INTx */
- bnad->num_rx = 1;
- bnad->num_tx = 1;
+ bnad->num_rx = BNAD_MAX_RX;
+ bnad->num_tx = BNAD_MAX_TX;
bnad->num_rxp_per_rx = rxps;
bnad->num_txq_per_tx = BNAD_MAX_TXQ_PER_TX;
}
/*
- * Adjusts the Q numbers, given a number of msix vectors
+ * Adjusts the Q numbers, given a number of max possible queues.
* Give preference to RSS as opposed to Tx priority Queues,
* in such a case, just use 1 Tx Q
* Called with bnad->bna_lock held b'cos of cfg_flags access
*/
static void
-bnad_q_num_adjust(struct bnad *bnad, int msix_vectors, int temp)
+bnad_q_num_adjust(struct bnad *bnad, int max_txq, int max_rxq)
{
- bnad->num_txq_per_tx = 1;
- if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) +
- bnad_rxqs_per_cq + BNAD_MAILBOX_MSIX_VECTORS) &&
- (bnad->cfg_flags & BNAD_CF_MSIX)) {
- bnad->num_rxp_per_rx = msix_vectors -
- (bnad->num_tx * bnad->num_txq_per_tx) -
- BNAD_MAILBOX_MSIX_VECTORS;
- } else
- bnad->num_rxp_per_rx = 1;
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX)) {
+ bnad->num_tx = bnad->num_txq_per_tx = 1;
+ bnad->num_rx = bnad->num_rxp_per_rx = 1;
+ return;
+ }
+
+ if (max_txq < BNAD_NUM_TXQ) {
+ bnad->num_txq_per_tx = 1;
+ bnad->num_tx = 1;
+ }
+
+ bnad->num_rx = 1;
+ bnad->num_rxp_per_rx = min((u32)(min((u32)num_online_cpus(),
+ (u32)(BNAD_MAX_RXP_PER_RX))),
+ (u32)max_rxq);
+ BNA_TO_POWER_OF_2(bnad->num_rxp_per_rx);
}
/* Enable / disable ioceth */
@@ -2359,7 +2400,7 @@ bnad_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
{
int i, err;
- for (i = 0; i < BNA_RES_T_MAX; i++) {
+ for (i = 0; i < res_val_max; i++) {
if (res_info[i].res_type == BNA_RES_T_MEM)
err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
else
@@ -2433,7 +2474,6 @@ bnad_enable_msix(struct bnad *bnad)
return;
intx_mode:
-
kfree(bnad->msix_table);
bnad->msix_table = NULL;
bnad->msix_num = 0;
@@ -2608,7 +2648,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
smp_mb__before_clear_bit();
clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
} else {
- netif_stop_queue(netdev);
+ netif_stop_subqueue(netdev, txq_id);
BNAD_UPDATE_CTR(bnad, netif_queue_stop);
}
@@ -2624,7 +2664,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
BNAD_UPDATE_CTR(bnad, netif_queue_stop);
return NETDEV_TX_BUSY;
} else {
- netif_wake_queue(netdev);
+ netif_wake_subqueue(netdev, txq_id);
BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
}
}
@@ -2649,7 +2689,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) {
vlan_tag =
- (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff);
+ ((tcb->priority & 0x7) << VLAN_PRIO_SHIFT)
+ | (vlan_tag & 0x1fff);
flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
}
@@ -2796,6 +2837,50 @@ bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
return stats;
}
+static bool bnad_is_iscsi(struct sk_buff *skb)
+{
+ u16 proto = 0;
+ struct tcphdr *th;
+
+ if (skb->protocol == htons(ETH_P_IP))
+ proto = ip_hdr(skb)->protocol;
+ else if (skb->protocol == htons(ETH_P_IPV6))
+ /* nexthdr may not be TCP immediately. */
+ proto = ipv6_hdr(skb)->nexthdr;
+ if (proto == IPPROTO_TCP) {
+ th = tcp_hdr(skb);
+ if (BNAD_IS_ISCSI_PKT(th))
+ return true;
+ }
+
+ return false;
+}
+
+static u16
+bnad_tx_select_queue(struct net_device *netdev, struct sk_buff *skb)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bna *bna = &bnad->bna;
+ u8 prio = 0;
+
+ if (bnad->num_txq_per_tx < BFI_TX_MAX_PRIO)
+ prio = 0;
+ else if (bna_is_iscsi_over_cee(&bnad->bna) && bnad_is_iscsi(skb))
+ prio = bna_iscsi_prio(bna);
+ else if (vlan_tx_tag_present(skb)) {
+ u8 pkt_vlan_prio = 0;
+ u16 pkt_vlan_tag = 0;
+ pkt_vlan_tag = (u16)vlan_tx_tag_get(skb);
+ pkt_vlan_prio = (pkt_vlan_tag & VLAN_PRIO_MASK)
+ >> VLAN_PRIO_SHIFT;
+ prio = bna_prio_allowed(bna, pkt_vlan_prio) ?
+ pkt_vlan_prio : bna_default_prio(bna);
+ } else
+ prio = bna_default_prio(bna);
+
+ return (u16)prio;
+}
+
static void
bnad_set_rx_mode(struct net_device *netdev)
{
@@ -3011,6 +3096,7 @@ bnad_netpoll(struct net_device *netdev)
static const struct net_device_ops bnad_netdev_ops = {
.ndo_open = bnad_open,
.ndo_stop = bnad_stop,
+ .ndo_select_queue = bnad_tx_select_queue,
.ndo_start_xmit = bnad_start_xmit,
.ndo_get_stats64 = bnad_get_stats64,
.ndo_set_rx_mode = bnad_set_rx_mode,
@@ -3208,7 +3294,7 @@ bnad_pci_probe(struct pci_dev *pdev,
* Allocates sizeof(struct net_device + struct bnad)
* bnad = netdev->priv
*/
- netdev = alloc_etherdev(sizeof(struct bnad));
+ netdev = alloc_etherdev_mq(sizeof(struct bnad), BNAD_MAX_TXQ);
if (!netdev) {
dev_err(&pdev->dev, "netdev allocation failed\n");
err = -ENOMEM;
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index c25e6e2..1b87b27 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -231,6 +231,15 @@ struct bnad_unmap_q {
/* Defined as bit positions */
#define BNAD_FP_IN_RX_PATH 0
+/*
+ * Deep Inspection : Checks if packet is ISCSI based on
+ * standard iSCSI port
+ */
+#define BNAD_TCP_ISCSI_PORT 3260
+#define BNAD_IS_ISCSI_PKT(_tch) \
+(((_tch)->source == ntohs(BNAD_TCP_ISCSI_PORT)) || \
+ ((_tch)->dest == ntohs(BNAD_TCP_ISCSI_PORT)))
+
struct bnad {
struct net_device *netdev;
--
1.7.1
^ permalink raw reply related
* [PATCH 33/45] bna: Device Init Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Do not return probe failure when device initialization fails so that the
driver stays loaded and the hardware is accessible for debugging.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bnad.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 6d1b82b..2b716ed 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -3308,19 +3308,21 @@ bnad_pci_probe(struct pci_dev *pdev,
spin_unlock_irqrestore(&bnad->bna_lock, flags);
err = bnad_res_alloc(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
- if (err)
+ if (err) {
+ err = -EIO;
goto disable_ioceth;
+ }
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_mod_init(&bnad->bna, &bnad->mod_res_info[0]);
- spin_unlock_irqrestore(&bnad->bna_lock, flags);
/* Get the burnt-in mac */
- spin_lock_irqsave(&bnad->bna_lock, flags);
bna_enet_perm_mac_get(&bna->enet, &bnad->perm_addr);
bnad_set_netdev_perm_addr(bnad);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ mutex_unlock(&bnad->conf_mutex);
+
/* Finally, reguister with net_device layer */
err = register_netdev(netdev);
if (err) {
@@ -3329,6 +3331,8 @@ bnad_pci_probe(struct pci_dev *pdev,
}
set_bit(BNAD_RF_NETDEV_REGISTERED, &bnad->run_flags);
+ return 0;
+
probe_success:
mutex_unlock(&bnad->conf_mutex);
return 0;
--
1.7.1
^ permalink raw reply related
* [PATCH 32/45] bna: TxRx Coalesce Settings Fix and Reorg PCI Probe Failure
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- The TX and Rx coalesce settings are programmed in steps of 5 us. The value
that are not divisible by 5 are rounded to the next lower number. This was
causing the value os 1 to 4 to be rounded to 0, which is an invalid setting.
- When creating Rx and Tx object, we are currently assigning the default
values of Rx and Tx coalescing_timeo. If these values are changed in
the driver to a different value, the change is lost during such
operations as MTU change. In order to avoid that, pass the configured
value of coalescing_timeo before Rx and Tx object creation.
- Fix bnad_tx_coalescing_timeo_set() so it applies to all the Tx objects.
- Fix uninitialization path in case of pci_probe failure.
- Added/Removed flags.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bnad.c | 46 ++++++++++++++++++++++++++++++----------------
drivers/net/bna/bnad.h | 9 +++++----
2 files changed, 35 insertions(+), 20 deletions(-)
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 684ff91..6d1b82b 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -1797,6 +1797,7 @@ bnad_setup_tx(struct bnad *bnad, u32 tx_id)
tx_config->num_txq = bnad->num_txq_per_tx;
tx_config->txq_depth = bnad->txq_depth;
tx_config->tx_type = BNA_TX_T_REGULAR;
+ tx_config->coalescing_timeo = bnad->tx_coalescing_timeo;
/* Initialize the tx event handlers */
tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup;
@@ -1857,6 +1858,7 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
{
rx_config->rx_type = BNA_RX_T_REGULAR;
rx_config->num_paths = bnad->num_rxp_per_rx;
+ rx_config->coalescing_timeo = bnad->rx_coalescing_timeo;
if (bnad->num_rxp_per_rx > 1) {
rx_config->rss_status = BNA_STATUS_T_ENABLED;
@@ -2017,12 +2019,15 @@ void
bnad_tx_coalescing_timeo_set(struct bnad *bnad)
{
struct bnad_tx_info *tx_info;
+ int i;
- tx_info = &bnad->tx_info[0];
- if (!tx_info->tx)
- return;
-
- bna_tx_coalescing_timeo_set(tx_info->tx, bnad->tx_coalescing_timeo);
+ for (i = 0; i < bnad->num_tx; i++) {
+ tx_info = &bnad->tx_info[i];
+ if (!tx_info->tx)
+ continue;
+ bna_tx_coalescing_timeo_set(tx_info->tx,
+ bnad->tx_coalescing_timeo);
+ }
}
/* Called with conf_lock & bnad->bna_lock held */
@@ -2726,7 +2731,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
- u32 size = frag->size;
+ u16 size = frag->size;
if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
vect_id = 0;
@@ -3248,7 +3253,7 @@ bnad_pci_probe(struct pci_dev *pdev,
/* Allocate resources from bna */
err = bnad_res_alloc(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
if (err)
- goto free_netdev;
+ goto drv_uninit;
bna = &bnad->bna;
@@ -3284,8 +3289,11 @@ bnad_pci_probe(struct pci_dev *pdev,
* This is a catastrophic error.
*/
err = bnad_ioceth_enable(bnad);
- if (err)
- goto disable_device;
+ if (err) {
+ pr_err("BNA: Initialization failed err=%d\n",
+ err);
+ goto probe_success;
+ }
spin_lock_irqsave(&bnad->bna_lock, flags);
if (bna_num_txq_set(bna, BNAD_NUM_TXQ + 1) ||
@@ -3301,7 +3309,7 @@ bnad_pci_probe(struct pci_dev *pdev,
err = bnad_res_alloc(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
if (err)
- goto disable_device;
+ goto disable_ioceth;
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_mod_init(&bnad->bna, &bnad->mod_res_info[0]);
@@ -3317,13 +3325,17 @@ bnad_pci_probe(struct pci_dev *pdev,
err = register_netdev(netdev);
if (err) {
pr_err("BNA : Registering with netdev failed\n");
- goto disable_device;
+ goto probe_uninit;
}
- mutex_unlock(&bnad->conf_mutex);
+ set_bit(BNAD_RF_NETDEV_REGISTERED, &bnad->run_flags);
+probe_success:
+ mutex_unlock(&bnad->conf_mutex);
return 0;
-disable_device:
+probe_uninit:
+ bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+disable_ioceth:
bnad_ioceth_disable(bnad);
del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
@@ -3331,13 +3343,14 @@ disable_device:
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
+drv_uninit:
bnad_disable_msix(bnad);
+ bnad_uninit(bnad);
pci_uninit:
bnad_pci_uninit(pdev);
+ mutex_unlock(&bnad->conf_mutex);
bnad_lock_uninit(bnad);
- bnad_uninit(bnad);
free_netdev:
free_netdev(netdev);
return err;
@@ -3358,7 +3371,8 @@ bnad_pci_remove(struct pci_dev *pdev)
bnad = netdev_priv(netdev);
bna = &bnad->bna;
- unregister_netdev(netdev);
+ if (test_and_clear_bit(BNAD_RF_NETDEV_REGISTERED, &bnad->run_flags))
+ unregister_netdev(netdev);
mutex_lock(&bnad->conf_mutex);
bnad_ioceth_disable(bnad);
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index 41ade02..c25e6e2 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -218,13 +218,14 @@ struct bnad_unmap_q {
/* Defines for run_flags bit-mask */
/* Set, tested & cleared using xxx_bit() functions */
/* Values indicated bit positions */
-#define BNAD_RF_CEE_RUNNING 1
+#define BNAD_RF_CEE_RUNNING 0
+#define BNAD_RF_MTU_SET 1
#define BNAD_RF_MBOX_IRQ_DISABLED 2
-#define BNAD_RF_RX_STARTED 3
+#define BNAD_RF_NETDEV_REGISTERED 3
#define BNAD_RF_DIM_TIMER_RUNNING 4
#define BNAD_RF_STATS_TIMER_RUNNING 5
-#define BNAD_RF_TX_SHUTDOWN_DELAYED 6
-#define BNAD_RF_RX_SHUTDOWN_DELAYED 7
+#define BNAD_RF_TX_PRIO_SET 6
+
/* Define for Fast Path flags */
/* Defined as bit positions */
--
1.7.1
^ permalink raw reply related
* [PATCH 31/45] bna: Configuration changes
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
bnad.c:
- Set number of Tx and Rx queues bassed on underlying hardware.
- Take VLAN header into account for MTU calculation
- Default to INTx mode when pci_enable_msix() fails.
- Set a bit in Rx poll routine, check and wait for that bit to be cleared
in the cleanup routine before proceeding.
bnad.h:
- Define separate macros for maximum and supported numbers of Tx and Rx
queues based on underlying hardware
bna.h:
- Define a macro to access the supported attributes for underlying hardware
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bna.h | 4 ++
drivers/net/bna/bnad.c | 136 ++++++++++++++++++++++++++++++-----------------
drivers/net/bna/bnad.h | 23 ++++++---
3 files changed, 107 insertions(+), 56 deletions(-)
diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h
index 518f3dd..66725d3 100644
--- a/drivers/net/bna/bna.h
+++ b/drivers/net/bna/bna.h
@@ -362,6 +362,8 @@ do { \
#define bna_is_prio_reconfig(_bna) ((_bna)->tx_mod.prio_reconfigured)
+#define bna_attr(_bna) (&(_bna)->ioceth.attr)
+
/**
*
* Inline functions
@@ -403,6 +405,8 @@ void bna_init(struct bna *bna, struct bnad *bnad,
struct bna_res_info *res_info);
void bna_mod_init(struct bna *bna, struct bna_res_info *res_info);
void bna_uninit(struct bna *bna);
+int bna_num_txq_set(struct bna *bna, int num_txq);
+int bna_num_rxp_set(struct bna *bna, int num_rxp);
void bna_stats_get(struct bna *bna);
void bna_get_perm_mac(struct bna *bna, u8 *mac);
void bna_hw_stats_get(struct bna *bna);
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 076f398..684ff91 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -441,9 +441,17 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
struct sk_buff *skb;
u32 flags, unmap_cons;
struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
+ struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
+
+ preempt_disable();
+
+ set_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
- if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))
+ if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) {
+ clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
+ preempt_enable();
return 0;
+ }
prefetch(bnad->netdev);
BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
@@ -551,6 +559,10 @@ next:
bna_ib_ack(ccb->i_dbell, 0);
}
+ clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
+
+ preempt_enable();
+
return packets;
}
@@ -1259,7 +1271,7 @@ bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info)
/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */
static int
bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
- uint txrx_id, struct bna_intr_info *intr_info)
+ u32 txrx_id, struct bna_intr_info *intr_info)
{
int i, vector_start = 0;
u32 cfg_flags;
@@ -1342,7 +1354,7 @@ bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info,
*/
static int
bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info,
- uint tx_id, int num_txqs)
+ u32 tx_id, int num_txqs)
{
int i;
int err;
@@ -1395,7 +1407,7 @@ bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info,
*/
static int
bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info,
- uint rx_id, int num_rxps)
+ u32 rx_id, int num_rxps)
{
int i;
int err;
@@ -1439,7 +1451,7 @@ bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
/* Allocates memory and interrupt resources for Tx object */
static int
bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
- uint tx_id)
+ u32 tx_id)
{
int i, err = 0;
@@ -1733,7 +1745,7 @@ bnad_napi_disable(struct bnad *bnad, u32 rx_id)
/* Should be held with conf_lock held */
void
-bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
+bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
{
struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
@@ -1757,6 +1769,7 @@ bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
spin_unlock_irqrestore(&bnad->bna_lock, flags);
tx_info->tx = NULL;
+ tx_info->tx_id = 0;
if (0 == tx_id)
tasklet_kill(&bnad->tx_free_tasklet);
@@ -1766,7 +1779,7 @@ bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
/* Should be held with conf_lock held */
int
-bnad_setup_tx(struct bnad *bnad, uint tx_id)
+bnad_setup_tx(struct bnad *bnad, u32 tx_id)
{
int err;
struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
@@ -1778,6 +1791,8 @@ bnad_setup_tx(struct bnad *bnad, uint tx_id)
struct bna_tx *tx;
unsigned long flags;
+ tx_info->tx_id = tx_id;
+
/* Initialize the Tx object configuration */
tx_config->num_txq = bnad->num_txq_per_tx;
tx_config->txq_depth = bnad->txq_depth;
@@ -1869,7 +1884,7 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
/* Called with mutex_lock(&bnad->conf_mutex) held */
void
-bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
+bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
{
struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
@@ -1912,7 +1927,7 @@ bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
/* Called with mutex_lock(&bnad->conf_mutex) held */
int
-bnad_setup_rx(struct bnad *bnad, uint rx_id)
+bnad_setup_rx(struct bnad *bnad, u32 rx_id)
{
int err;
struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
@@ -1924,6 +1939,8 @@ bnad_setup_rx(struct bnad *bnad, uint rx_id)
struct bna_rx *rx;
unsigned long flags;
+ rx_info->rx_id = rx_id;
+
/* Initialize the Rx object configuration */
bnad_init_rx_config(bnad, rx_config);
@@ -2138,7 +2155,7 @@ void
bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
{
struct bfi_enet_stats_mac *mac_stats;
- u64 bmap;
+ u32 bmap;
int i;
mac_stats = &bnad->stats.bna_stats->hw_stats.mac_stats;
@@ -2253,7 +2270,7 @@ bnad_q_num_init(struct bnad *bnad)
bnad->num_rx = 1;
bnad->num_tx = 1;
bnad->num_rxp_per_rx = rxps;
- bnad->num_txq_per_tx = BNAD_TXQ_NUM;
+ bnad->num_txq_per_tx = BNAD_MAX_TXQ_PER_TX;
}
/*
@@ -2263,7 +2280,7 @@ bnad_q_num_init(struct bnad *bnad)
* Called with bnad->bna_lock held b'cos of cfg_flags access
*/
static void
-bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
+bnad_q_num_adjust(struct bnad *bnad, int msix_vectors, int temp)
{
bnad->num_txq_per_tx = 1;
if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) +
@@ -2317,12 +2334,12 @@ bnad_ioceth_enable(struct bnad *bnad)
/* Free BNA resources */
static void
-bnad_res_free(struct bnad *bnad)
+bnad_res_free(struct bnad *bnad, struct bna_res_info *res_info,
+ u32 res_val_max)
{
int i;
- struct bna_res_info *res_info = &bnad->res_info[0];
- for (i = 0; i < BNA_RES_T_MAX; i++) {
+ for (i = 0; i < res_val_max; i++) {
if (res_info[i].res_type == BNA_RES_T_MEM)
bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
else
@@ -2332,10 +2349,10 @@ bnad_res_free(struct bnad *bnad)
/* Allocates memory and interrupt resources for BNA */
static int
-bnad_res_alloc(struct bnad *bnad)
+bnad_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+ u32 res_val_max)
{
int i, err;
- struct bna_res_info *res_info = &bnad->res_info[0];
for (i = 0; i < BNA_RES_T_MAX; i++) {
if (res_info[i].res_type == BNA_RES_T_MEM)
@@ -2349,7 +2366,7 @@ bnad_res_alloc(struct bnad *bnad)
return 0;
err_return:
- bnad_res_free(bnad);
+ bnad_res_free(bnad, res_info, res_val_max);
return err;
}
@@ -2385,7 +2402,7 @@ bnad_enable_msix(struct bnad *bnad)
spin_lock_irqsave(&bnad->bna_lock, flags);
/* ret = #of vectors that we got */
- bnad_q_num_adjust(bnad, ret);
+ bnad_q_num_adjust(bnad, ret, 0);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx)
@@ -2393,6 +2410,9 @@ bnad_enable_msix(struct bnad *bnad)
* bnad->num_rxp_per_rx) +
BNAD_MAILBOX_MSIX_VECTORS;
+ if (bnad->msix_num > ret)
+ goto intx_mode;
+
/* Try once more with adjusted numbers */
/* If this fails, fall back to INTx */
ret = pci_enable_msix(bnad->pcidev, bnad->msix_table,
@@ -2402,6 +2422,9 @@ bnad_enable_msix(struct bnad *bnad)
} else if (ret < 0)
goto intx_mode;
+
+ pci_intx(bnad->pcidev, 0);
+
return;
intx_mode:
@@ -2460,7 +2483,7 @@ bnad_open(struct net_device *netdev)
pause_config.tx_pause = 0;
pause_config.rx_pause = 0;
- mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
+ mtu = ETH_HLEN + VLAN_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_enet_mtu_set(&bnad->bna.enet, mtu, NULL);
@@ -2534,16 +2557,15 @@ static netdev_tx_t
bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct bnad *bnad = netdev_priv(netdev);
+ u32 txq_id = 0;
+ struct bna_tcb *tcb = bnad->tx_info[0].tcb[txq_id];
u16 txq_prod, vlan_tag = 0;
u32 unmap_prod, wis, wis_used, wi_range;
u32 vectors, vect_id, i, acked;
- u32 tx_id;
int err;
- struct bnad_tx_info *tx_info;
- struct bna_tcb *tcb;
- struct bnad_unmap_q *unmap_q;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
dma_addr_t dma_addr;
struct bna_txq_entry *txqent;
u16 flags;
@@ -2554,15 +2576,9 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- tx_id = 0;
-
- tx_info = &bnad->tx_info[tx_id];
- tcb = tx_info->tcb[tx_id];
- unmap_q = tcb->unmap_q;
-
/*
* Takes care of the Tx that is scheduled between clearing the flag
- * and the netif_stop_queue() call.
+ * and the netif_stop_all_queue() call.
*/
if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
dev_kfree_skb(skb);
@@ -2576,9 +2592,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
acked = 0;
- if (unlikely
- (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
- vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+ if (unlikely(wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+ vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
if ((u16) (*tcb->hw_consumer_index) !=
tcb->consumer_index &&
!test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
@@ -3190,12 +3205,15 @@ bnad_pci_probe(struct pci_dev *pdev,
*/
netdev = alloc_etherdev(sizeof(struct bnad));
if (!netdev) {
- dev_err(&pdev->dev, "alloc_etherdev failed\n");
+ dev_err(&pdev->dev, "netdev allocation failed\n");
err = -ENOMEM;
return err;
}
bnad = netdev_priv(netdev);
+ bnad_lock_init(bnad);
+
+ mutex_lock(&bnad->conf_mutex);
/*
* PCI initialization
* Output : using_dac = 1 for 64 bit DMA
@@ -3205,7 +3223,6 @@ bnad_pci_probe(struct pci_dev *pdev,
if (err)
goto free_netdev;
- bnad_lock_init(bnad);
/*
* Initialize bnad structure
* Setup relation between pci_dev & netdev
@@ -3214,6 +3231,7 @@ bnad_pci_probe(struct pci_dev *pdev,
err = bnad_init(bnad, pdev, netdev);
if (err)
goto pci_uninit;
+
/* Initialize netdev structure, set up ethtool ops */
bnad_netdev_init(bnad, using_dac);
@@ -3223,10 +3241,12 @@ bnad_pci_probe(struct pci_dev *pdev,
bnad_enable_msix(bnad);
/* Get resource requirement form bna */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
bna_res_req(&bnad->res_info[0]);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
/* Allocate resources from bna */
- err = bnad_res_alloc(bnad);
+ err = bnad_res_alloc(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
if (err)
goto free_netdev;
@@ -3238,8 +3258,6 @@ bnad_pci_probe(struct pci_dev *pdev,
pcidev_info.device_id = bnad->pcidev->device;
pcidev_info.pci_bar_kva = bnad->bar0;
- mutex_lock(&bnad->conf_mutex);
-
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -3262,10 +3280,32 @@ bnad_pci_probe(struct pci_dev *pdev,
/*
* Start the chip
- * Don't care even if err != 0, bna state machine will
- * deal with it
+ * If the call back comes with error, we bail out.
+ * This is a catastrophic error.
*/
err = bnad_ioceth_enable(bnad);
+ if (err)
+ goto disable_device;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bna_num_txq_set(bna, BNAD_NUM_TXQ + 1) ||
+ bna_num_rxp_set(bna, BNAD_NUM_RXP + 1)) {
+ bnad_q_num_adjust(bnad, bna_attr(bna)->num_txq - 1,
+ bna_attr(bna)->num_rxp - 1);
+ if (bna_num_txq_set(bna, BNAD_NUM_TXQ + 1) ||
+ bna_num_rxp_set(bna, BNAD_NUM_RXP + 1))
+ err = -EIO;
+ }
+ bna_mod_res_req(&bnad->bna, &bnad->mod_res_info[0]);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ err = bnad_res_alloc(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+ if (err)
+ goto disable_device;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_mod_init(&bnad->bna, &bnad->mod_res_info[0]);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
/* Get the burnt-in mac */
spin_lock_irqsave(&bnad->bna_lock, flags);
@@ -3273,19 +3313,17 @@ bnad_pci_probe(struct pci_dev *pdev,
bnad_set_netdev_perm_addr(bnad);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- mutex_unlock(&bnad->conf_mutex);
-
/* Finally, reguister with net_device layer */
err = register_netdev(netdev);
if (err) {
pr_err("BNA : Registering with netdev failed\n");
goto disable_device;
}
+ mutex_unlock(&bnad->conf_mutex);
return 0;
disable_device:
- mutex_lock(&bnad->conf_mutex);
bnad_ioceth_disable(bnad);
del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
@@ -3293,9 +3331,8 @@ disable_device:
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- mutex_unlock(&bnad->conf_mutex);
-
- bnad_res_free(bnad);
+ bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+ bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
bnad_disable_msix(bnad);
pci_uninit:
bnad_pci_uninit(pdev);
@@ -3331,11 +3368,12 @@ bnad_pci_remove(struct pci_dev *pdev)
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_uninit(bna);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- mutex_unlock(&bnad->conf_mutex);
- bnad_res_free(bnad);
+ bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+ bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
bnad_disable_msix(bnad);
bnad_pci_uninit(pdev);
+ mutex_unlock(&bnad->conf_mutex);
bnad_lock_uninit(bnad);
bnad_uninit(bnad);
free_netdev(netdev);
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
index 6a161b0..41ade02 100644
--- a/drivers/net/bna/bnad.h
+++ b/drivers/net/bna/bnad.h
@@ -38,12 +38,11 @@
#define BNAD_RXQ_DEPTH 2048
#define BNAD_MAX_TX 1
-#define BNAD_MAX_TXQ_PER_TX 8 /* 8 priority queues */
-#define BNAD_TXQ_NUM 1
+#define BNAD_MAX_TXQ_PER_TX 8
#define BNAD_MAX_RX 1
#define BNAD_MAX_RXP_PER_RX 16
-#define BNAD_MAX_RXQ_PER_RXP 2
+#define BNAD_MAX_RXQ_PER_RXP 2
/*
* Control structure pointed to ccb->ctrl, which
@@ -95,6 +94,13 @@ struct bnad_rx_ctrl {
#define BNAD_RXQ_REFILL 0
#define BNAD_RXQ_STARTED 1
+/* Resource limits */
+#define BNAD_MAX_TXQ (BNAD_MAX_TX * BNAD_MAX_TXQ_PER_TX)
+#define BNAD_MAX_RXP (BNAD_MAX_RX * BNAD_MAX_RXP_PER_RX)
+
+#define BNAD_NUM_TXQ (bnad->num_tx * bnad->num_txq_per_tx)
+#define BNAD_NUM_RXP (bnad->num_rx * bnad->num_rxp_per_rx)
+
/*
* DATA STRUCTURES
*/
@@ -179,12 +185,14 @@ struct bnad_rx_res_info {
struct bnad_tx_info {
struct bna_tx *tx; /* 1:1 between tx_info & tx */
struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
+ u32 tx_id;
} ____cacheline_aligned;
struct bnad_rx_info {
struct bna_rx *rx; /* 1:1 between rx_info & rx */
struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXP_PER_RX];
+ u32 rx_id;
} ____cacheline_aligned;
/* Unmap queues for Tx / Rx cleanup */
@@ -274,6 +282,7 @@ struct bnad {
/* Control path resources, memory & irq */
struct bna_res_info res_info[BNA_RES_T_MAX];
+ struct bna_res_info mod_res_info[BNA_MOD_RES_T_MAX];
struct bnad_tx_res_info tx_res_info[BNAD_MAX_TX];
struct bnad_rx_res_info rx_res_info[BNAD_MAX_RX];
@@ -311,10 +320,10 @@ extern void bnad_set_ethtool_ops(struct net_device *netdev);
extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad);
extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad);
-extern int bnad_setup_rx(struct bnad *bnad, uint rx_id);
-extern int bnad_setup_tx(struct bnad *bnad, uint tx_id);
-extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id);
-extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id);
+extern int bnad_setup_rx(struct bnad *bnad, u32 rx_id);
+extern int bnad_setup_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_cleanup_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_cleanup_rx(struct bnad *bnad, u32 rx_id);
/* Timer start/stop protos */
extern void bnad_dim_timer_start(struct bnad *bnad);
--
1.7.1
^ permalink raw reply related
* [PATCH 30/45] bna: Add HW Semaphore Unlock Logic
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Added logic to unlock hw semaphore if the previos FW boot was from boot
code (flash based) and the current FW initialization attempt is from OS
driver.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 78cdc2b..940c94a 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -58,6 +58,7 @@ static bool bfa_nw_auto_recover = true;
/*
* forward declarations
*/
+static void bfa_ioc_hw_sem_init(struct bfa_ioc *ioc);
static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
@@ -691,6 +692,7 @@ bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf)
{
+ bfa_ioc_hw_sem_init(iocpf->ioc);
bfa_ioc_hw_sem_get(iocpf->ioc);
}
@@ -1263,6 +1265,29 @@ bfa_nw_ioc_sem_release(void __iomem *sem_reg)
}
static void
+bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_image_hdr fwhdr;
+ u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ if (fwstate == BFI_IOC_UNINIT)
+ return;
+
+ bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+
+ if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
+ return;
+
+ writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+
+ /*
+ * Try to lock and then unlock the semaphore.
+ */
+ readl(ioc->ioc_regs.ioc_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+}
+
+static void
bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
{
u32 r32;
--
1.7.1
^ permalink raw reply related
* [PATCH 29/45] bna: Add Sub-System Device ID Info
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- 1860 has CNA personality with SSID 22 for PCI functions.
- Preserve the same SSID numbering so that FCoE drivers claim adapters with
no-asic block (default personality).
Can we get this out?
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 10 ++++++++++
drivers/net/bna/bfa_ioc.c | 3 ++-
drivers/net/bna/bfa_ioc.h | 1 +
3 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index e7dd91f..3e5d096 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -261,4 +261,14 @@ enum {
#define bfa_asic_id_ctc(device) \
(bfa_asic_id_ct(device) || bfa_asic_id_ct2(device))
+/**
+ * PCI sub-system device and vendor ID information
+ */
+enum {
+ BFA_PCI_FCOE_SSDEVICE_ID = 0x14,
+ BFA_PCI_CT2_SSID_FCoE = 0x22,
+ BFA_PCI_CT2_SSID_ETH = 0x23,
+ BFA_PCI_CT2_SSID_FC = 0x24,
+};
+
#endif /* __BFA_DEFS_H__ */
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 2130b5a..78cdc2b 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -1987,7 +1987,8 @@ bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
case BFA_PCI_DEVICE_ID_CT2:
ioc->asic_gen = BFI_ASIC_GEN_CT2;
- if (clscode == BFI_PCIFN_CLASS_FC) {
+ if (clscode == BFI_PCIFN_CLASS_FC &&
+ pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
ioc->asic_mode = BFI_ASIC_MODE_FC16;
ioc->fcmode = true;
} else {
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index a9f24e2..0f7dba1 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -35,6 +35,7 @@ struct bfa_pcidev {
int pci_slot;
u8 pci_func;
u16 device_id;
+ u16 ssid;
void __iomem *pci_bar_kva;
};
--
1.7.1
^ permalink raw reply related
* [PATCH 28/45] bna: Add New IOC event
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- ACQ_ADDR IOC state and its state machine implementation.
- The changes related to FAA enable/disable/query in firmware
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 1 +
drivers/net/bna/bfa_defs_status.h | 9 +++++
drivers/net/bna/bfa_ioc.c | 69 ++++++++++++++++++++++++++++++++++++-
drivers/net/bna/bfi.h | 1 +
4 files changed, 79 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index 621d50b..e7dd91f 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -125,6 +125,7 @@ enum bfa_ioc_state {
BFA_IOC_FWMISMATCH = 11, /*!< IOC f/w different from drivers */
BFA_IOC_ENABLING = 12, /*!< IOC is being enabled */
BFA_IOC_HWFAIL = 13, /*!< PCI mapping doesn't exist */
+ BFA_IOC_ACQ_ADDR = 14, /*!< Acquiring addr from fabric */
};
/**
diff --git a/drivers/net/bna/bfa_defs_status.h b/drivers/net/bna/bfa_defs_status.h
index 7c5fe6c..bf7f87a 100644
--- a/drivers/net/bna/bfa_defs_status.h
+++ b/drivers/net/bna/bfa_defs_status.h
@@ -205,6 +205,15 @@ enum bfa_status {
BFA_STATUS_BOOT_CODE_TIMEDOUT = 177,
BFA_STATUS_NO_VPORT_LOCK = 178,
BFA_STATUS_VPORT_NO_CNFG = 179,
+ BFA_STATUS_FEATURE_NOT_SUPPORTED = 180,
+ BFA_STATUS_ENTRY_EXISTS = 181,
+ BFA_STATUS_ENTRY_NOT_EXISTS = 182,
+ BFA_STATUS_NO_CHANGE = 183,
+ BFA_STATUS_DISABLED = 184,
+ BFA_STATUS_FAA_ENABLED = 185,
+ BFA_STATUS_FAA_DISABLED = 186,
+ BFA_STATUS_FAA_ACQUIRED = 187,
+ BFA_STATUS_FAA_ACQ_ADDR = 188,
BFA_STATUS_MAX_VAL
};
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 2dd19d2..2130b5a 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -113,6 +113,7 @@ enum ioc_event {
IOC_E_HWERROR = 10, /*!< hardware error interrupt */
IOC_E_TIMEOUT = 11, /*!< timeout */
IOC_E_HWFAILED = 12, /*!< PCI mapping failure notice */
+ IOC_E_FWRSP_ACQ_ADDR = 13, /*!< Acquiring address */
};
bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
@@ -125,6 +126,7 @@ bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, acq_addr, struct bfa_ioc, enum ioc_event);
static struct bfa_sm_table ioc_sm_table[] = {
{BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -137,6 +139,7 @@ static struct bfa_sm_table ioc_sm_table[] = {
{BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
{BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
{BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
+ {BFA_SM(bfa_ioc_sm_acq_addr), BFA_IOC_ACQ_ADDR},
};
/**
@@ -351,9 +354,17 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
case IOC_E_FWRSP_GETATTR:
del_timer(&ioc->ioc_timer);
bfa_ioc_check_attr_wwns(ioc);
+ bfa_ioc_hb_monitor(ioc);
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
+ case IOC_E_FWRSP_ACQ_ADDR:
+ del_timer(&ioc->ioc_timer);
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_FAA_ACQ_ADDR);
+ bfa_ioc_hb_monitor(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_acq_addr);
+ break;
+
case IOC_E_PFFAILED:
case IOC_E_HWERROR:
del_timer(&ioc->ioc_timer);
@@ -378,11 +389,54 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
}
}
+/**
+ * Acquiring address from fabric (entry function)
+ */
+static void
+bfa_ioc_sm_acq_addr_entry(struct bfa_ioc *ioc)
+{
+}
+
+/**
+ * Acquiring address from the fabric
+ */
+static void
+bfa_ioc_sm_acq_addr(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_GETATTR:
+ bfa_ioc_check_attr_wwns(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ break;
+
+ case IOC_E_PFFAILED:
+ case IOC_E_HWERROR:
+ bfa_ioc_hb_stop(ioc);
+ case IOC_E_HBFAIL:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+ if (event != IOC_E_PFFAILED)
+ bfa_iocpf_getattrfail(ioc);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hb_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_ENABLE:
+ break;
+
+ default:
+ bfa_sm_fault(event);
+ }
+}
+
static void
bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
{
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
- bfa_ioc_hb_monitor(ioc);
+ bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
}
static void
@@ -1639,6 +1693,15 @@ bfa_ioc_getattr_reply(struct bfa_ioc *ioc)
}
/**
+ * Response from f/w that IOC attributes are not ready
+ */
+static void
+bfa_ioc_acq_addr_reply(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_ACQ_ADDR);
+}
+
+/**
* Attach time initialization of mbox logic.
*/
static void
@@ -1856,6 +1919,10 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
bfa_ioc_getattr_reply(ioc);
break;
+ case BFI_IOC_I2H_ACQ_ADDR_REPLY:
+ bfa_ioc_acq_addr_reply(ioc);
+ break;
+
default:
BUG_ON(1);
}
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
index d95eeb2..8d238a7 100644
--- a/drivers/net/bna/bfi.h
+++ b/drivers/net/bna/bfi.h
@@ -225,6 +225,7 @@ enum bfi_ioc_i2h_msgs {
BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
BFI_IOC_I2H_HBEAT = BFA_I2HM(4),
+ BFI_IOC_I2H_ACQ_ADDR_REPLY = BFA_I2HM(5),
};
/**
--
1.7.1
^ permalink raw reply related
* [PATCH 27/45] bna: IOC Event Name Change
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Changed event name IOC_E_PFAILED to IOC_E_PFFAILED
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index beb63f9..2dd19d2 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -108,7 +108,7 @@ enum ioc_event {
IOC_E_ENABLED = 5, /*!< f/w enabled */
IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */
IOC_E_DISABLED = 7, /*!< f/w disabled */
- IOC_E_PFAILED = 8, /*!< failure notice by iocpf sm */
+ IOC_E_PFFAILED = 8, /*!< failure notice by iocpf sm */
IOC_E_HBFAIL = 9, /*!< heartbeat failure */
IOC_E_HWERROR = 10, /*!< hardware error interrupt */
IOC_E_TIMEOUT = 11, /*!< timeout */
@@ -299,12 +299,12 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
break;
- case IOC_E_PFAILED:
+ case IOC_E_PFFAILED:
/* !!! fall through !!! */
case IOC_E_HWERROR:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- if (event != IOC_E_PFAILED)
+ if (event != IOC_E_PFFAILED)
bfa_iocpf_initfail(ioc);
break;
@@ -354,14 +354,14 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
- case IOC_E_PFAILED:
+ case IOC_E_PFFAILED:
case IOC_E_HWERROR:
del_timer(&ioc->ioc_timer);
/* fall through */
case IOC_E_TIMEOUT:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- if (event != IOC_E_PFAILED)
+ if (event != IOC_E_PFFAILED)
bfa_iocpf_getattrfail(ioc);
break;
@@ -397,7 +397,7 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
- case IOC_E_PFAILED:
+ case IOC_E_PFFAILED:
case IOC_E_HWERROR:
bfa_ioc_hb_stop(ioc);
/* !!! fall through !!! */
@@ -409,7 +409,7 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
bfa_ioc_fail_notify(ioc);
- if (event != IOC_E_PFAILED)
+ if (event != IOC_E_PFFAILED)
bfa_iocpf_fail(ioc);
break;
@@ -501,14 +501,14 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
break;
- case IOC_E_PFAILED:
+ case IOC_E_PFFAILED:
case IOC_E_HWERROR:
/**
* Initialization retry failed.
*/
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- if (event != IOC_E_PFAILED)
+ if (event != IOC_E_PFFAILED)
bfa_iocpf_initfail(ioc);
break;
@@ -1722,7 +1722,7 @@ bfa_ioc_pf_disabled(struct bfa_ioc *ioc)
static void
bfa_ioc_pf_failed(struct bfa_ioc *ioc)
{
- bfa_fsm_send_event(ioc, IOC_E_PFAILED);
+ bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
}
static void
--
1.7.1
^ permalink raw reply related
* [PATCH 26/45] bna: Ethfn LPU DMA Read Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- In new HW, LPU cannot perform DMA read from host memory for PFs with
Ethernet functionality. As a result, BFI_ENET command processing (which
uses the msgq implementation and relies on LPU doing DMA read from host
memoty) will not work
- To fix this, msgq sends mailbox message to Host to request data from a
specified memory area, Host copies the data from specifies memory area
to mailbox and notifies the LPU, LPU upon receiving all fragments of
data, continues processing Enet commands
- Host processes LPU mailbox read status interrupt and schedules mailbox
poll routine. Host implements handler for BFI_MSGQ_I2H_CMDQ_COPY_REQ
message and uses BFI_MSGQ_H2I_CMDQ_COPY_RSP message to send data to LPU.
Msgq module in FW implements mailbox based cmdq read routine
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 30 ++++++++++++++++++------------
drivers/net/bna/bfa_ioc.h | 5 +++++
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 216d0d1..beb63f9 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -2058,22 +2058,28 @@ bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
struct bfi_mbmsg m;
int mc;
- if (!bfa_ioc_msgget(ioc, &m))
- return;
+ if (bfa_ioc_msgget(ioc, &m)) {
+ /**
+ * Treat IOC message class as special.
+ */
+ mc = m.mh.msg_class;
+ if (mc == BFI_MC_IOC) {
+ bfa_ioc_isr(ioc, &m);
+ return;
+ }
- /**
- * Treat IOC message class as special.
- */
- mc = m.mh.msg_class;
- if (mc == BFI_MC_IOC) {
- bfa_ioc_isr(ioc, &m);
- return;
+ if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
+ return;
+
+ mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
}
- if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
- return;
+ bfa_ioc_lpu_read_stat(ioc);
- mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
+ /**
+ * Try to send pending mailbox commands
+ */
+ bfa_ioc_mbox_poll(ioc);
}
void
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index 07e1a9d..a9f24e2 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -281,6 +281,11 @@ void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
#define bfa_ioc_ownership_reset(__ioc) \
((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+#define bfa_ioc_lpu_read_stat(__ioc) do { \
+ if ((__ioc)->ioc_hwif->ioc_lpu_read_stat) \
+ ((__ioc)->ioc_hwif->ioc_lpu_read_stat(__ioc)); \
+} while (0)
+
void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
void bfa_nw_ioc_set_ct2_hwif(struct bfa_ioc *ioc);
--
1.7.1
^ permalink raw reply related
* [PATCH 25/45] bna: Move FW Init to HW Init and Disable Hang Unmapped Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Move the bfa_ioc_poll_fwinit() function call out of bfa_ioc_boot() and put
it inside the caller of bfa_ioc_boot(), which is bfa_ioc_hwinit()
- Diag memtest call bfa_ioc_boot() to download memtest specific fw code.
Inside bfa_ioc_boot(), it called bfa_ioc_poll_fwinit() which start a timer,
with a timeout duration much shorter than the memtest timer. As a result,
this poll timer expired, and cause the assert. But eventually, the
memtest complete successfully.
- Handle the case where PCI mapping goes away when IOCPF state machine is
waiting for semaphore.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 1 +
drivers/net/bna/bfa_ioc.c | 91 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index e89830f..621d50b 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -124,6 +124,7 @@ enum bfa_ioc_state {
BFA_IOC_DISABLED = 10, /*!< IOC is disabled */
BFA_IOC_FWMISMATCH = 11, /*!< IOC f/w different from drivers */
BFA_IOC_ENABLING = 12, /*!< IOC is being enabled */
+ BFA_IOC_HWFAIL = 13, /*!< PCI mapping doesn't exist */
};
/**
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index a38f5cd..216d0d1 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -79,6 +79,7 @@ static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc);
static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc);
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
u32 boot_param);
@@ -111,6 +112,7 @@ enum ioc_event {
IOC_E_HBFAIL = 9, /*!< heartbeat failure */
IOC_E_HWERROR = 10, /*!< hardware error interrupt */
IOC_E_TIMEOUT = 11, /*!< timeout */
+ IOC_E_HWFAILED = 12, /*!< PCI mapping failure notice */
};
bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
@@ -122,6 +124,7 @@ bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event);
static struct bfa_sm_table ioc_sm_table[] = {
{BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -133,6 +136,7 @@ static struct bfa_sm_table ioc_sm_table[] = {
{BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
{BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
{BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
+ {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
};
/**
@@ -164,6 +168,7 @@ enum iocpf_event {
IOCPF_E_GETATTRFAIL = 9, /*!< init fail notice by ioc sm */
IOCPF_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */
IOCPF_E_TIMEOUT = 11, /*!< f/w response timeout */
+ IOCPF_E_SEM_ERROR = 12, /*!< h/w sem mapping error */
};
/**
@@ -303,6 +308,11 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
bfa_iocpf_initfail(ioc);
break;
+ case IOC_E_HWFAILED:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
+ break;
+
case IOC_E_DISABLE:
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
break;
@@ -434,6 +444,11 @@ bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
bfa_iocpf_fail(ioc);
break;
+ case IOC_E_HWFAILED:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
+ bfa_ioc_disable_comp(ioc);
+ break;
+
default:
bfa_sm_fault(event);
}
@@ -497,6 +512,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
bfa_iocpf_initfail(ioc);
break;
+ case IOC_E_HWFAILED:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
+ break;
+
case IOC_E_ENABLE:
break;
@@ -548,6 +568,36 @@ bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
}
}
+static void
+bfa_ioc_sm_hwfail_entry(struct bfa_ioc *ioc)
+{
+}
+
+/**
+ * IOC failure.
+ */
+static void
+bfa_ioc_sm_hwfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+
+ case IOC_E_ENABLE:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ break;
+
+ case IOC_E_DISABLE:
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+ break;
+
+ default:
+ bfa_sm_fault(event);
+ }
+}
+
/**
* IOCPF State Machine
*/
@@ -616,6 +666,11 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
}
break;
+ case IOCPF_E_SEM_ERROR:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_ioc_pf_hwfailed(ioc);
+ break;
+
case IOCPF_E_DISABLE:
bfa_ioc_hw_sem_get_cancel(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
@@ -705,6 +760,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
}
break;
+ case IOCPF_E_SEM_ERROR:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_ioc_pf_hwfailed(ioc);
+ break;
+
case IOCPF_E_DISABLE:
bfa_ioc_hw_sem_get_cancel(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -894,6 +954,11 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
break;
+ case IOCPF_E_SEM_ERROR:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_ioc_pf_hwfailed(ioc);
+ break;
+
case IOCPF_E_FAIL:
break;
@@ -955,6 +1020,11 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
break;
+ case IOCPF_E_SEM_ERROR:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_ioc_pf_hwfailed(ioc);
+ break;
+
case IOCPF_E_DISABLE:
bfa_ioc_hw_sem_get_cancel(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -1044,6 +1114,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
}
break;
+ case IOCPF_E_SEM_ERROR:
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+ bfa_ioc_pf_hwfailed(ioc);
+ break;
+
case IOCPF_E_DISABLE:
bfa_ioc_hw_sem_get_cancel(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -1143,7 +1218,11 @@ bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
* will return 1. Semaphore is released by writing 1 to the register
*/
r32 = readl(ioc->ioc_regs.ioc_sem_reg);
- if (r32 == 0) {
+ if (r32 == ~0) {
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
+ return;
+ }
+ if (!(r32 & 1)) {
bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
return;
}
@@ -1334,6 +1413,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
if (!fwvalid) {
bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
+ bfa_ioc_poll_fwinit(ioc);
return;
}
@@ -1364,6 +1444,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
* Initialize the h/w for any other states.
*/
bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
+ bfa_ioc_poll_fwinit(ioc);
}
void
@@ -1645,6 +1726,12 @@ bfa_ioc_pf_failed(struct bfa_ioc *ioc)
}
static void
+bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
+}
+
+static void
bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc)
{
/**
@@ -1701,9 +1788,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
bfa_ioc_msgflush(ioc);
bfa_ioc_download_fw(ioc, boot_type, boot_env);
-
bfa_ioc_lpu_start(ioc);
- bfa_ioc_poll_fwinit(ioc);
}
/**
--
1.7.1
^ permalink raw reply related
* [PATCH 24/45] bna: Mboxq Flush When Ioc Disabled
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- If there is a command pending in the mailbox, bfa_ioc_mbox_queue() enqueues
the mailbox command to a pending command queue. Entries in this queue are
not flushed when IOC is disabled. As a result, when IOC is re-enabled again,
the stale entries in the pending command queue are posted to the mailbox.
When these mailbox commands are processed by the FW and responses are sent,
unexpected events are received by other modules' FSMs (f.e. bfa_msgq) which
have not posted any mailbox commands after IOC was enabled.
- Flush the pending mailbox command queue when IOC is disabled. Rename
bfa_ioc_mbox_hbfail to bfa_ioc_mbox_flush. Call bfa_ioc_mbox_flush
from bfa_iocpf_sm_disabled_entry()
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 33776da..a38f5cd 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -69,7 +69,7 @@ static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc);
static void bfa_ioc_hb_stop(struct bfa_ioc *ioc);
static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
-static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc);
static void bfa_ioc_recover(struct bfa_ioc *ioc);
static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
@@ -908,6 +908,7 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf)
{
+ bfa_ioc_mbox_flush(iocpf->ioc);
bfa_ioc_pf_disabled(iocpf->ioc);
}
@@ -1012,7 +1013,7 @@ bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf)
/**
* Flush any queued up mailbox requests.
*/
- bfa_ioc_mbox_hbfail(iocpf->ioc);
+ bfa_ioc_mbox_flush(iocpf->ioc);
bfa_ioc_hw_sem_get(iocpf->ioc);
}
@@ -1606,7 +1607,7 @@ bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
* Cleanup any pending requests.
*/
static void
-bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
+bfa_ioc_mbox_flush(struct bfa_ioc *ioc)
{
struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
struct bfa_mbox_cmd *cmd;
--
1.7.1
^ permalink raw reply related
* [PATCH 23/45] bna: Added Defines for Multi TXQ Support
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Chnage details:
- Added new Macros - bna_prio_allow(), bna_iscsi_prio(), bna_default_nw_prio(),
bna_is_iscsi_over_cee(), bna_is_prio_reconfig()
- Construction of priority indirection table to be used by bnad to direct
packets into TxQs
- Making available valid priority map, iscsi priority, default priority
and priority indirection table to bnad through macros
- Set/reset prio_reconfigured when txq reconfigured/not reconfigured
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bna.h | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h
index b342bdb..518f3dd 100644
--- a/drivers/net/bna/bna.h
+++ b/drivers/net/bna/bna.h
@@ -32,6 +32,7 @@ extern u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
#define BNA_MESSAGE_SIZE 256
#define bna_is_small_rxq(_id) ((_id) & 0x1)
+#define bna_is_header_rxq(_id) bna_is_small_rxq(_id)
#define BNA_MAC_IS_EQUAL(_mac1, _mac2) \
(!memcmp((_mac1), (_mac2), sizeof(mac_t)))
@@ -351,6 +352,16 @@ do { \
} \
} while (0)
+#define bna_prio_allowed(_bna, _prio) ((_bna)->tx_mod.prio_map & (1 << _prio))
+
+#define bna_iscsi_prio(_bna) ((_bna)->tx_mod.iscsi_prio)
+
+#define bna_default_prio(_bna) ((_bna)->tx_mod.default_prio)
+
+#define bna_is_iscsi_over_cee(_bna) ((_bna)->tx_mod.iscsi_over_cee)
+
+#define bna_is_prio_reconfig(_bna) ((_bna)->tx_mod.prio_reconfigured)
+
/**
*
* Inline functions
--
1.7.1
^ permalink raw reply related
* [PATCH 22/45] bna: Capability Map and MFG Block Changes for New HW
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Added capability map and generic model name scheme for manufacturing block.
- Updated the mfginfo command to handle old h/w alongside new one.
- Changed firmware code to reduce card types for 1860 cards and derived card
model from card type, capability fields and initial capability.
- Removed explicit set/get fcmode. Now this is based on PCI device properties.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_defs.h | 20 +++++++---
drivers/net/bna/bfa_defs_mfg_comm.h | 72 ++++++++++++++++++++++++++---------
drivers/net/bna/bfa_ioc.c | 5 +-
3 files changed, 71 insertions(+), 26 deletions(-)
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
index f5909d0..e89830f 100644
--- a/drivers/net/bna/bfa_defs.h
+++ b/drivers/net/bna/bfa_defs.h
@@ -220,15 +220,23 @@ struct bfa_mfg_block {
u8 rsv[2];
char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)];
char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)];
- char
- supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
- char
- supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
+ char supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
+ char supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
mac_t mfg_mac; /*!< mac address */
u8 num_mac; /*!< number of mac addresses */
u8 rsv2;
- u32 mfg_type; /*!< card type */
- u8 rsv3[108];
+ u32 card_type; /*!< card type */
+ char cap_nic; /*!< capability nic */
+ char cap_cna; /*!< capability cna */
+ char cap_hba; /*!< capability hba */
+ char cap_fc16g; /*!< capability fc 16g */
+ char cap_sriov; /*!< capability sriov */
+ char cap_mezz; /*!< capability mezz */
+ u8 rsv3;
+ u8 mfg_nports; /*!< number of ports */
+ char media[8]; /*!< xfi/xaui */
+ char initial_mode[8];/*!< initial mode: hba/cna/nic */
+ u8 rsv4[84];
u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */
};
diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h
index 885ef3a..2f00813 100644
--- a/drivers/net/bna/bfa_defs_mfg_comm.h
+++ b/drivers/net/bna/bfa_defs_mfg_comm.h
@@ -19,11 +19,12 @@
#define __BFA_DEFS_MFG_COMM_H__
#include "cna.h"
+#include "bfa_defs.h"
/**
* Manufacturing block version
*/
-#define BFA_MFG_VERSION 2
+#define BFA_MFG_VERSION 3
#define BFA_MFG_VERSION_UNINIT 0xFF
/**
@@ -60,20 +61,17 @@ enum {
BFA_MFG_TYPE_ASTRA = 807, /*!< Astra mezz card */
BFA_MFG_TYPE_LIGHTNING_P0 = 902, /*!< Lightning mezz card - old */
BFA_MFG_TYPE_LIGHTNING = 1741, /*!< Lightning mezz card */
+ BFA_MFG_TYPE_PROWLER_F = 1560, /*!< Prowler FC only cards */
+ BFA_MFG_TYPE_PROWLER_N = 1410, /*!< Prowler NIC only cards */
+ BFA_MFG_TYPE_PROWLER_C = 1710, /*!< Prowler CNA only cards */
+ BFA_MFG_TYPE_PROWLER_D = 1860, /*!< Prowler Dual cards */
+ BFA_MFG_TYPE_CHINOOK = 1867, /*!< Chinook cards */
BFA_MFG_TYPE_INVALID = 0, /*!< Invalid card type */
};
#pragma pack(1)
/**
- * Check if 1-port card
- */
-#define bfa_mfg_is_1port(type) (( \
- (type) == BFA_MFG_TYPE_FC8P1 || \
- (type) == BFA_MFG_TYPE_FC4P1 || \
- (type) == BFA_MFG_TYPE_CNA10P1))
-
-/**
* Check if Mezz card
*/
#define bfa_mfg_is_mezz(type) (( \
@@ -81,7 +79,8 @@ enum {
(type) == BFA_MFG_TYPE_WANCHESE || \
(type) == BFA_MFG_TYPE_ASTRA || \
(type) == BFA_MFG_TYPE_LIGHTNING_P0 || \
- (type) == BFA_MFG_TYPE_LIGHTNING))
+ (type) == BFA_MFG_TYPE_LIGHTNING || \
+ (type) == BFA_MFG_TYPE_CHINOOK))
/**
* Check if card type valid
@@ -93,14 +92,16 @@ enum {
(type) == BFA_MFG_TYPE_FC4P1 || \
(type) == BFA_MFG_TYPE_CNA10P2 || \
(type) == BFA_MFG_TYPE_CNA10P1 || \
+ (type) == BFA_MFG_TYPE_PROWLER_F || \
+ (type) == BFA_MFG_TYPE_PROWLER_N || \
+ (type) == BFA_MFG_TYPE_PROWLER_C || \
+ (type) == BFA_MFG_TYPE_PROWLER_D || \
bfa_mfg_is_mezz(type)))
-#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \
+#define bfa_mfg_adapter_prop_init_flash_cb(mfgblk, prop) \
do { \
- switch ((card_type)) { \
+ switch ((mfgblk)->card_type) { \
case BFA_MFG_TYPE_FC8P2: \
- case BFA_MFG_TYPE_JAYHAWK: \
- case BFA_MFG_TYPE_ASTRA: \
(prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
BFI_ADAPTER_SETP(SPEED, 8); \
break; \
@@ -116,22 +117,57 @@ do { \
(prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
BFI_ADAPTER_SETP(SPEED, 4); \
break; \
+ default: \
+ (prop) = BFI_ADAPTER_UNSUPP; \
+ } \
+} while (0)
+
+#define bfa_mfg_adapter_prop_init_flash_ct(mfgblk, prop) \
+do { \
+ switch ((mfgblk)->card_type) { \
+ case BFA_MFG_TYPE_JAYHAWK: \
+ case BFA_MFG_TYPE_ASTRA: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 8); \
+ break; \
case BFA_MFG_TYPE_CNA10P2: \
case BFA_MFG_TYPE_WANCHESE: \
case BFA_MFG_TYPE_LIGHTNING_P0: \
case BFA_MFG_TYPE_LIGHTNING: \
- (prop) = BFI_ADAPTER_SETP(NPORTS, 2); \
- (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 10); \
break; \
case BFA_MFG_TYPE_CNA10P1: \
- (prop) = BFI_ADAPTER_SETP(NPORTS, 1); \
- (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
+ BFI_ADAPTER_SETP(SPEED, 10); \
break; \
default: \
(prop) = BFI_ADAPTER_UNSUPP; \
} \
} while (0)
+#define bfa_mfg_adapter_prop_init_flash_ct2(mfgblk, prop) \
+do { \
+ int sp, np = (mfgblk)->mfg_nports; \
+ switch ((mfgblk)->card_type) { \
+ case BFA_MFG_TYPE_PROWLER_F: \
+ case BFA_MFG_TYPE_CHINOOK: \
+ sp = 16; \
+ break; \
+ case BFA_MFG_TYPE_PROWLER_N: \
+ case BFA_MFG_TYPE_PROWLER_C: \
+ sp = 10; \
+ break; \
+ case BFA_MFG_TYPE_PROWLER_D: \
+ sp = 16; \
+ break; \
+ default: \
+ sp = 16; \
+ } \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, np) | \
+ BFI_ADAPTER_SETP(SPEED, sp); \
+} while (0)
+
enum {
CB_GPIO_TTV = (1), /*!< TTV debug capable cards */
CB_GPIO_FC8P2 = (2), /*!< 8G 2port FC card */
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index 3e38cbb..33776da 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -1834,9 +1834,10 @@ bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
case BFA_PCI_DEVICE_ID_CT2:
ioc->asic_gen = BFI_ASIC_GEN_CT2;
- if (clscode == BFI_PCIFN_CLASS_FC)
+ if (clscode == BFI_PCIFN_CLASS_FC) {
ioc->asic_mode = BFI_ASIC_MODE_FC16;
- else {
+ ioc->fcmode = true;
+ } else {
ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
ioc->asic_mode = BFI_ASIC_MODE_ETH;
}
--
1.7.1
^ permalink raw reply related
* [PATCH 21/45] bna: Remove Reset Call Back
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Remove call to reset_cbfn() from bfa_ioc_boot().
- Call bfa_ioc_fail_notify() to notify other modules/driver after setting IOC
sm state to fail_retry/fail.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index df26a8a..3e38cbb 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -392,12 +392,13 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
bfa_ioc_hb_stop(ioc);
/* !!! fall through !!! */
case IOC_E_HBFAIL:
- bfa_ioc_fail_notify(ioc);
if (ioc->iocpf.auto_recover)
bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
else
bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+ bfa_ioc_fail_notify(ioc);
+
if (event != IOC_E_PFAILED)
bfa_iocpf_fail(ioc);
break;
@@ -758,6 +759,9 @@ bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
{
mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
+ /**
+ * Enable Interrupts before sending fw IOC ENABLE cmd.
+ */
iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
bfa_ioc_send_enable(iocpf->ioc);
}
@@ -1697,10 +1701,6 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
bfa_ioc_msgflush(ioc);
bfa_ioc_download_fw(ioc, boot_type, boot_env);
- /**
- * Enable interrupts just before starting LPU
- */
- ioc->cbfn->reset_cbfn(ioc->bfa);
bfa_ioc_lpu_start(ioc);
bfa_ioc_poll_fwinit(ioc);
}
--
1.7.1
^ permalink raw reply related
* [PATCH 20/45] bna: MBOX IRQ Sync Vector Num Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- Fixed the vector number used for syncing MBox IRQ
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bnad.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index cd2b921..076f398 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -2180,7 +2180,7 @@ bnad_mbox_irq_sync(struct bnad *bnad)
spin_lock_irqsave(&bnad->bna_lock, flags);
if (bnad->cfg_flags & BNAD_CF_MSIX)
- irq = bnad->msix_table[bnad->msix_num - 1].vector;
+ irq = bnad->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector;
else
irq = bnad->pcidev->irq;
spin_unlock_irqrestore(&bnad->bna_lock, flags);
--
1.7.1
^ permalink raw reply related
* [PATCH 19/45] bna: HW Type Check Fix
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change detils:
- The macro bfa_ioc_is_cna() will return true if IOC type is BFA_IOC_TYPE_FCoE
or BFA_IOC_TYPE_LL
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index bcc9acc..07e1a9d 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -234,7 +234,8 @@ struct bfa_ioc_hwif {
#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
#define bfa_ioc_asic_gen(__ioc) ((__ioc)->asic_gen)
#define bfa_ioc_is_cna(__ioc) \
- (bfa_nw_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
+ ((bfa_nw_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) || \
+ (bfa_nw_ioc_get_type(ioc) == BFA_IOC_TYPE_LL))
#define bfa_ioc_fetch_stats(__ioc, __stats) \
(((__stats)->drv_stats) = (__ioc)->stats)
#define bfa_ioc_clr_stats(__ioc) \
--
1.7.1
^ permalink raw reply related
* [PATCH 18/45] bna: Implement Polling Mechanism for FW Ready
From: Rasesh Mody @ 2011-07-18 8:22 UTC (permalink / raw)
To: davem, netdev; +Cc: adapter_linux_open_src_team, dradovan, Rasesh Mody
In-Reply-To: <1310977385-5268-1-git-send-email-rmody@brocade.com>
Change details:
- A poll mechanism replaces the current interrupt based FW READY method.
- The timer based poll routine in IOC will query the ioc_fwstate register
to see if there is a state change in FW, and sends the READY event.
- Removed infrastructure needed to support mbox READY event from fw as well as
IOC code.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/bna/bfa_ioc.c | 117 +++++++++++++++-----------------------------
drivers/net/bna/bfa_ioc.h | 5 +-
drivers/net/bna/bfi.h | 11 +----
3 files changed, 45 insertions(+), 88 deletions(-)
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
index fcc9278..df26a8a 100644
--- a/drivers/net/bna/bfa_ioc.c
+++ b/drivers/net/bna/bfa_ioc.c
@@ -61,6 +61,7 @@ static bool bfa_nw_auto_recover = true;
static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_poll_fwinit(struct bfa_ioc *ioc);
static void bfa_ioc_send_enable(struct bfa_ioc *ioc);
static void bfa_ioc_send_disable(struct bfa_ioc *ioc);
static void bfa_ioc_send_getattr(struct bfa_ioc *ioc);
@@ -77,7 +78,6 @@ static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc);
static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
-static void bfa_ioc_pf_initfailed(struct bfa_ioc *ioc);
static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
@@ -107,11 +107,10 @@ enum ioc_event {
IOC_E_ENABLED = 5, /*!< f/w enabled */
IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */
IOC_E_DISABLED = 7, /*!< f/w disabled */
- IOC_E_INITFAILED = 8, /*!< failure notice by iocpf sm */
- IOC_E_PFAILED = 9, /*!< failure notice by iocpf sm */
- IOC_E_HBFAIL = 10, /*!< heartbeat failure */
- IOC_E_HWERROR = 11, /*!< hardware error interrupt */
- IOC_E_TIMEOUT = 12, /*!< timeout */
+ IOC_E_PFAILED = 8, /*!< failure notice by iocpf sm */
+ IOC_E_HBFAIL = 9, /*!< heartbeat failure */
+ IOC_E_HWERROR = 10, /*!< hardware error interrupt */
+ IOC_E_TIMEOUT = 11, /*!< timeout */
};
bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
@@ -299,7 +298,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
/* !!! fall through !!! */
case IOC_E_HWERROR:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
if (event != IOC_E_PFAILED)
bfa_iocpf_initfail(ioc);
break;
@@ -351,7 +350,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
/* fall through */
case IOC_E_TIMEOUT:
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
if (event != IOC_E_PFAILED)
bfa_iocpf_getattrfail(ioc);
break;
@@ -492,14 +491,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
* Initialization retry failed.
*/
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
if (event != IOC_E_PFAILED)
bfa_iocpf_initfail(ioc);
break;
- case IOC_E_INITFAILED:
- bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
- break;
-
case IOC_E_ENABLE:
break;
@@ -561,7 +557,7 @@ bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
static void
bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf)
{
- iocpf->retry_count = 0;
+ iocpf->fw_mismatch_notified = false;
iocpf->auto_recover = bfa_nw_auto_recover;
}
@@ -605,7 +601,6 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
case IOCPF_E_SEMLOCKED:
if (bfa_ioc_firmware_lock(ioc)) {
if (bfa_ioc_sync_start(ioc)) {
- iocpf->retry_count = 0;
bfa_ioc_sync_join(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
} else {
@@ -643,10 +638,10 @@ static void
bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
{
/* Call only the first time sm enters fwmismatch state. */
- if (iocpf->retry_count == 0)
+ if (iocpf->fw_mismatch_notified == false)
bfa_ioc_pf_fwmismatch(iocpf->ioc);
- iocpf->retry_count++;
+ iocpf->fw_mismatch_notified = true;
mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
}
@@ -722,8 +717,7 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf)
{
- mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
- msecs_to_jiffies(BFA_IOC_TOV));
+ iocpf->poll_time = 0;
bfa_ioc_reset(iocpf->ioc, 0);
}
@@ -738,20 +732,12 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWREADY:
- del_timer(&ioc->iocpf_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
break;
- case IOCPF_E_INITFAIL:
- del_timer(&ioc->iocpf_timer);
- /*
- * !!! fall through !!!
- */
-
case IOCPF_E_TIMEOUT:
bfa_nw_ioc_hw_sem_release(ioc);
- if (event == IOCPF_E_TIMEOUT)
- bfa_ioc_pf_failed(ioc);
+ bfa_ioc_pf_failed(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
break;
@@ -772,6 +758,7 @@ bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
{
mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
msecs_to_jiffies(BFA_IOC_TOV));
+ iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
bfa_ioc_send_enable(iocpf->ioc);
}
@@ -809,21 +796,11 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
break;
- case IOCPF_E_FWREADY:
- bfa_ioc_send_enable(ioc);
- break;
-
default:
bfa_sm_fault(event);
}
}
-static bool
-bfa_nw_ioc_is_operational(struct bfa_ioc *ioc)
-{
- return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
-}
-
static void
bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
{
@@ -833,8 +810,6 @@ bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
static void
bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
{
- struct bfa_ioc *ioc = iocpf->ioc;
-
switch (event) {
case IOCPF_E_DISABLE:
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
@@ -848,14 +823,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
break;
- case IOCPF_E_FWREADY:
- bfa_ioc_pf_failed(ioc);
- if (bfa_nw_ioc_is_operational(ioc))
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
- else
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
- break;
-
default:
bfa_sm_fault(event);
}
@@ -879,7 +846,6 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_FWRSP_DISABLE:
- case IOCPF_E_FWREADY:
del_timer(&ioc->iocpf_timer);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
break;
@@ -948,7 +914,6 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_ENABLE:
- iocpf->retry_count = 0;
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
break;
@@ -979,20 +944,10 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_SEMLOCKED:
bfa_ioc_notify_fail(ioc);
- bfa_ioc_sync_ack(ioc);
- iocpf->retry_count++;
- if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
- bfa_ioc_sync_leave(ioc);
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
- } else {
- if (bfa_ioc_sync_complete(ioc))
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
- else {
- bfa_nw_ioc_hw_sem_release(ioc);
- bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
- }
- }
+ bfa_ioc_sync_leave(ioc);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
break;
case IOCPF_E_DISABLE:
@@ -1017,7 +972,6 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
static void
bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf)
{
- bfa_ioc_pf_initfailed(iocpf->ioc);
}
/**
@@ -1068,11 +1022,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
switch (event) {
case IOCPF_E_SEMLOCKED:
- iocpf->retry_count = 0;
bfa_ioc_sync_ack(ioc);
bfa_ioc_notify_fail(ioc);
if (!iocpf->auto_recover) {
bfa_ioc_sync_leave(ioc);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
bfa_nw_ioc_hw_sem_release(ioc);
bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
} else {
@@ -1383,7 +1337,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
* just wait for an initialization completion interrupt.
*/
if (ioc_fwstate == BFI_IOC_INITING) {
- ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_ioc_poll_fwinit(ioc);
return;
}
@@ -1397,7 +1351,6 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
* be flushed. Otherwise MSI-X interrupts are not delivered.
*/
bfa_ioc_msgflush(ioc);
- ioc->cbfn->reset_cbfn(ioc->bfa);
bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
return;
}
@@ -1681,12 +1634,6 @@ bfa_ioc_pf_disabled(struct bfa_ioc *ioc)
}
static void
-bfa_ioc_pf_initfailed(struct bfa_ioc *ioc)
-{
- bfa_fsm_send_event(ioc, IOC_E_INITFAILED);
-}
-
-static void
bfa_ioc_pf_failed(struct bfa_ioc *ioc)
{
bfa_fsm_send_event(ioc, IOC_E_PFAILED);
@@ -1755,6 +1702,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
*/
ioc->cbfn->reset_cbfn(ioc->bfa);
bfa_ioc_lpu_start(ioc);
+ bfa_ioc_poll_fwinit(ioc);
}
/**
@@ -1810,10 +1758,6 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
case BFI_IOC_I2H_HBEAT:
break;
- case BFI_IOC_I2H_READY_EVENT:
- bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY);
- break;
-
case BFI_IOC_I2H_ENABLE_REPLY:
bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
break;
@@ -2341,3 +2285,22 @@ bfa_nw_iocpf_sem_timeout(void *ioc_arg)
bfa_ioc_hw_sem_get(ioc);
}
+
+static void
+bfa_ioc_poll_fwinit(struct bfa_ioc *ioc)
+{
+ u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ if (fwstate == BFI_IOC_DISABLED) {
+ bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
+ return;
+ }
+
+ if (ioc->iocpf.poll_time >= BFA_IOC_TOV) {
+ bfa_nw_iocpf_timeout(ioc);
+ } else {
+ ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
+ mod_timer(&ioc->ioc_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_POLL_TOV));
+ }
+}
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
index 95358a2..bcc9acc 100644
--- a/drivers/net/bna/bfa_ioc.h
+++ b/drivers/net/bna/bfa_ioc.h
@@ -26,7 +26,7 @@
#define BFA_IOC_TOV 3000 /* msecs */
#define BFA_IOC_HWSEM_TOV 500 /* msecs */
#define BFA_IOC_HB_TOV 500 /* msecs */
-#define BFA_IOC_HWINIT_MAX 5
+#define BFA_IOC_POLL_TOV 200 /* msecs */
/**
* PCI device information required by IOC
@@ -170,8 +170,9 @@ struct bfa_ioc_hbfail_notify {
struct bfa_iocpf {
bfa_fsm_t fsm;
struct bfa_ioc *ioc;
- u32 retry_count;
+ bool fw_mismatch_notified;
bool auto_recover;
+ u32 poll_time;
};
struct bfa_ioc {
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
index 284c3f8..d95eeb2 100644
--- a/drivers/net/bna/bfi.h
+++ b/drivers/net/bna/bfi.h
@@ -224,8 +224,7 @@ enum bfi_ioc_i2h_msgs {
BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
- BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
- BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
+ BFI_IOC_I2H_HBEAT = BFA_I2HM(4),
};
/**
@@ -333,12 +332,6 @@ enum bfi_port_mode {
/**
* BFI_IOC_I2H_READY_EVENT message
*/
-struct bfi_ioc_rdy_event {
- struct bfi_mhdr mh; /*!< common msg header */
- u8 init_status; /*!< init event status */
- u8 rsvd[3];
-};
-
struct bfi_ioc_hbeat {
struct bfi_mhdr mh; /*!< common msg header */
u32 hb_count; /*!< current heart beat count */
@@ -426,7 +419,7 @@ union bfi_ioc_h2i_msg_u {
*/
union bfi_ioc_i2h_msg_u {
struct bfi_mhdr mh;
- struct bfi_ioc_rdy_event rdy_event;
+ struct bfi_ioc_ctrl_reply fw_event;
u32 mboxmsg[BFI_IOC_MSGSZ];
};
--
1.7.1
^ 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