diff options
Diffstat (limited to 'drivers/net/chelsio/sge.c')
-rwxr-xr-x[-rw-r--r--] | drivers/net/chelsio/sge.c | 44 |
1 files changed, 17 insertions, 27 deletions
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 4436662..b301c04 100644..100755 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -986,11 +986,10 @@ void t1_sge_get_port_stats(const struct sge *sge, int port, for_each_possible_cpu(cpu) { struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[port], cpu); - ss->rx_packets += st->rx_packets; ss->rx_cso_good += st->rx_cso_good; - ss->tx_packets += st->tx_packets; ss->tx_cso += st->tx_cso; ss->tx_tso += st->tx_tso; + ss->tx_need_hdrroom += st->tx_need_hdrroom; ss->vlan_xtract += st->vlan_xtract; ss->vlan_insert += st->vlan_insert; } @@ -1380,7 +1379,6 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) __skb_pull(skb, sizeof(*p)); st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id()); - st->rx_packets++; skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev); skb->dev->last_rx = jiffies; @@ -1624,11 +1622,9 @@ int t1_poll(struct napi_struct *napi, int budget) { struct adapter *adapter = container_of(napi, struct adapter, napi); struct net_device *dev = adapter->port[0].dev; - int work_done; - - work_done = process_responses(adapter, budget); + int work_done = process_responses(adapter, budget); - if (likely(!responses_pending(adapter))) { + if (likely(work_done < budget)) { netif_rx_complete(dev, napi); writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); @@ -1848,7 +1844,8 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct adapter *adapter = dev->priv; struct sge *sge = adapter->sge; - struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], smp_processor_id()); + struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], + smp_processor_id()); struct cpl_tx_pkt *cpl; struct sk_buff *orig_skb = skb; int ret; @@ -1856,6 +1853,18 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->protocol == htons(ETH_P_CPL5)) goto send; + /* + * We are using a non-standard hard_header_len. + * Allocate more header room in the rare cases it is not big enough. + */ + if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) { + skb = skb_realloc_headroom(skb, sizeof(struct cpl_tx_pkt_lso)); + ++st->tx_need_hdrroom; + dev_kfree_skb_any(orig_skb); + if (!skb) + return NETDEV_TX_OK; + } + if (skb_shinfo(skb)->gso_size) { int eth_type; struct cpl_tx_pkt_lso *hdr; @@ -1889,24 +1898,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - /* - * We are using a non-standard hard_header_len and some kernel - * components, such as pktgen, do not handle it right. - * Complain when this happens but try to fix things up. - */ - if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) { - pr_debug("%s: headroom %d header_len %d\n", dev->name, - skb_headroom(skb), dev->hard_header_len); - - if (net_ratelimit()) - printk(KERN_ERR "%s: inadequate headroom in " - "Tx packet\n", dev->name); - skb = skb_realloc_headroom(skb, sizeof(*cpl)); - dev_kfree_skb_any(orig_skb); - if (!skb) - return NETDEV_TX_OK; - } - if (!(adapter->flags & UDP_CSUM_CAPABLE) && skb->ip_summed == CHECKSUM_PARTIAL && ip_hdr(skb)->protocol == IPPROTO_UDP) { @@ -1952,7 +1943,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl->vlan_valid = 0; send: - st->tx_packets++; dev->trans_start = jiffies; ret = t1_sge_tx(skb, adapter, 0, dev); |