diff options
Diffstat (limited to 'drivers/net/chelsio')
-rw-r--r-- | drivers/net/chelsio/common.h | 2 | ||||
-rw-r--r-- | drivers/net/chelsio/cxgb2.c | 74 | ||||
-rw-r--r-- | drivers/net/chelsio/espi.c | 2 | ||||
-rw-r--r-- | drivers/net/chelsio/espi.h | 1 | ||||
-rw-r--r-- | drivers/net/chelsio/pm3393.c | 112 | ||||
-rw-r--r-- | drivers/net/chelsio/sge.c | 50 | ||||
-rw-r--r-- | drivers/net/chelsio/sge.h | 5 | ||||
-rw-r--r-- | drivers/net/chelsio/subr.c | 9 |
8 files changed, 131 insertions, 124 deletions
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index 846ca5383d3..4bd2455b0fe 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -379,7 +379,7 @@ extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config extern const struct board_info *t1_get_board_info(unsigned int board_id); extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid, unsigned short ssid); -extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data); +extern int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data); extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, struct adapter_params *p); extern int t1_init_hw_modules(adapter_t *adapter); diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 2dbf8dc116c..a509337eab2 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -374,7 +374,9 @@ static char stats_strings[][ETH_GSTRING_LEN] = { "TxInternalMACXmitError", "TxFramesWithExcessiveDeferral", "TxFCSErrors", - + "TxJumboFramesOk", + "TxJumboOctetsOk", + "RxOctetsOK", "RxOctetsBad", "RxUnicastFramesOK", @@ -392,16 +394,17 @@ static char stats_strings[][ETH_GSTRING_LEN] = { "RxInRangeLengthErrors", "RxOutOfRangeLengthField", "RxFrameTooLongErrors", + "RxJumboFramesOk", + "RxJumboOctetsOk", /* Port stats */ - "RxPackets", "RxCsumGood", - "TxPackets", "TxCsumOffload", "TxTso", "RxVlan", "TxVlan", - + "TxNeedHeadroom", + /* Interrupt stats */ "rx drops", "pure_rsps", @@ -463,23 +466,56 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, const struct cmac_statistics *s; const struct sge_intr_counts *t; struct sge_port_stats ss; - unsigned int len; s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); - - len = sizeof(u64)*(&s->TxFCSErrors + 1 - &s->TxOctetsOK); - memcpy(data, &s->TxOctetsOK, len); - data += len; - - len = sizeof(u64)*(&s->RxFrameTooLongErrors + 1 - &s->RxOctetsOK); - memcpy(data, &s->RxOctetsOK, len); - data += len; - + t = t1_sge_get_intr_counts(adapter->sge); t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss); - memcpy(data, &ss, sizeof(ss)); - data += sizeof(ss); - t = t1_sge_get_intr_counts(adapter->sge); + *data++ = s->TxOctetsOK; + *data++ = s->TxOctetsBad; + *data++ = s->TxUnicastFramesOK; + *data++ = s->TxMulticastFramesOK; + *data++ = s->TxBroadcastFramesOK; + *data++ = s->TxPauseFrames; + *data++ = s->TxFramesWithDeferredXmissions; + *data++ = s->TxLateCollisions; + *data++ = s->TxTotalCollisions; + *data++ = s->TxFramesAbortedDueToXSCollisions; + *data++ = s->TxUnderrun; + *data++ = s->TxLengthErrors; + *data++ = s->TxInternalMACXmitError; + *data++ = s->TxFramesWithExcessiveDeferral; + *data++ = s->TxFCSErrors; + *data++ = s->TxJumboFramesOK; + *data++ = s->TxJumboOctetsOK; + + *data++ = s->RxOctetsOK; + *data++ = s->RxOctetsBad; + *data++ = s->RxUnicastFramesOK; + *data++ = s->RxMulticastFramesOK; + *data++ = s->RxBroadcastFramesOK; + *data++ = s->RxPauseFrames; + *data++ = s->RxFCSErrors; + *data++ = s->RxAlignErrors; + *data++ = s->RxSymbolErrors; + *data++ = s->RxDataErrors; + *data++ = s->RxSequenceErrors; + *data++ = s->RxRuntErrors; + *data++ = s->RxJabberErrors; + *data++ = s->RxInternalMACRcvError; + *data++ = s->RxInRangeLengthErrors; + *data++ = s->RxOutOfRangeLengthField; + *data++ = s->RxFrameTooLongErrors; + *data++ = s->RxJumboFramesOK; + *data++ = s->RxJumboOctetsOK; + + *data++ = ss.rx_cso_good; + *data++ = ss.tx_cso; + *data++ = ss.tx_tso; + *data++ = ss.vlan_xtract; + *data++ = ss.vlan_insert; + *data++ = ss.tx_need_hdrroom; + *data++ = t->rx_drops; *data++ = t->pure_rsps; *data++ = t->unhandled_irqs; @@ -778,7 +814,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, e->magic = EEPROM_MAGIC(adapter); for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32)) - t1_seeprom_read(adapter, i, (u32 *)&buf[i]); + t1_seeprom_read(adapter, i, (__le32 *)&buf[i]); memcpy(data, buf + e->offset, e->len); return 0; } @@ -1006,7 +1042,7 @@ static int __devinit init_one(struct pci_dev *pdev, pci_using_dac = 1; if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { - CH_ERR("%s: unable to obtain 64-bit DMA for" + CH_ERR("%s: unable to obtain 64-bit DMA for " "consistent allocations\n", pci_name(pdev)); err = -ENODEV; goto out_disable_pdev; diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index d7c5406a6c3..1e0749e000b 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c @@ -297,6 +297,7 @@ struct peespi *t1_espi_create(adapter_t *adapter) return espi; } +#if 0 void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) { struct peespi *espi = adapter->espi; @@ -309,6 +310,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); spin_unlock(&espi->lock); } +#endif /* 0 */ u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) { diff --git a/drivers/net/chelsio/espi.h b/drivers/net/chelsio/espi.h index 84f2c98bc4c..5694aad4fbc 100644 --- a/drivers/net/chelsio/espi.h +++ b/drivers/net/chelsio/espi.h @@ -62,7 +62,6 @@ void t1_espi_intr_disable(struct peespi *); int t1_espi_intr_handler(struct peespi *); const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi); -void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val); u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait); int t1_espi_get_mon_t204(adapter_t *, u32 *, u8); diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c index 678778a8d13..2117c4fbb10 100644 --- a/drivers/net/chelsio/pm3393.c +++ b/drivers/net/chelsio/pm3393.c @@ -45,7 +45,7 @@ #include <linux/crc32.h> -#define OFFSET(REG_ADDR) (REG_ADDR << 2) +#define OFFSET(REG_ADDR) ((REG_ADDR) << 2) /* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */ #define MAX_FRAME_SIZE 9600 @@ -428,69 +428,26 @@ static int pm3393_set_speed_duplex_fc(struct cmac *cmac, int speed, int duplex, return 0; } -static void pm3393_rmon_update(struct adapter *adapter, u32 offs, u64 *val, - int over) -{ - u32 val0, val1, val2; - - t1_tpi_read(adapter, offs, &val0); - t1_tpi_read(adapter, offs + 4, &val1); - t1_tpi_read(adapter, offs + 8, &val2); - - *val &= ~0ull << 40; - *val |= val0 & 0xffff; - *val |= (val1 & 0xffff) << 16; - *val |= (u64)(val2 & 0xff) << 32; - - if (over) - *val += 1ull << 40; +#define RMON_UPDATE(mac, name, stat_name) \ +{ \ + t1_tpi_read((mac)->adapter, OFFSET(name), &val0); \ + t1_tpi_read((mac)->adapter, OFFSET((name)+1), &val1); \ + t1_tpi_read((mac)->adapter, OFFSET((name)+2), &val2); \ + (mac)->stats.stat_name = (u64)(val0 & 0xffff) | \ + ((u64)(val1 & 0xffff) << 16) | \ + ((u64)(val2 & 0xff) << 32) | \ + ((mac)->stats.stat_name & \ + 0xffffff0000000000ULL); \ + if (ro & \ + (1ULL << ((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2))) \ + (mac)->stats.stat_name += 1ULL << 40; \ } static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, int flag) { - static struct { - unsigned int reg; - unsigned int offset; - } hw_stats [] = { - -#define HW_STAT(name, stat_name) \ - { name, (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL } - - /* Rx stats */ - HW_STAT(RxOctetsReceivedOK, RxOctetsOK), - HW_STAT(RxUnicastFramesReceivedOK, RxUnicastFramesOK), - HW_STAT(RxMulticastFramesReceivedOK, RxMulticastFramesOK), - HW_STAT(RxBroadcastFramesReceivedOK, RxBroadcastFramesOK), - HW_STAT(RxPAUSEMACCtrlFramesReceived, RxPauseFrames), - HW_STAT(RxFrameCheckSequenceErrors, RxFCSErrors), - HW_STAT(RxFramesLostDueToInternalMACErrors, - RxInternalMACRcvError), - HW_STAT(RxSymbolErrors, RxSymbolErrors), - HW_STAT(RxInRangeLengthErrors, RxInRangeLengthErrors), - HW_STAT(RxFramesTooLongErrors , RxFrameTooLongErrors), - HW_STAT(RxJabbers, RxJabberErrors), - HW_STAT(RxFragments, RxRuntErrors), - HW_STAT(RxUndersizedFrames, RxRuntErrors), - HW_STAT(RxJumboFramesReceivedOK, RxJumboFramesOK), - HW_STAT(RxJumboOctetsReceivedOK, RxJumboOctetsOK), - - /* Tx stats */ - HW_STAT(TxOctetsTransmittedOK, TxOctetsOK), - HW_STAT(TxFramesLostDueToInternalMACTransmissionError, - TxInternalMACXmitError), - HW_STAT(TxTransmitSystemError, TxFCSErrors), - HW_STAT(TxUnicastFramesTransmittedOK, TxUnicastFramesOK), - HW_STAT(TxMulticastFramesTransmittedOK, TxMulticastFramesOK), - HW_STAT(TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK), - HW_STAT(TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames), - HW_STAT(TxJumboFramesReceivedOK, TxJumboFramesOK), - HW_STAT(TxJumboOctetsReceivedOK, TxJumboOctetsOK) - }, *p = hw_stats; - u64 ro; - u32 val0, val1, val2, val3; - u64 *stats = (u64 *) &mac->stats; - unsigned int i; + u64 ro; + u32 val0, val1, val2, val3; /* Snap the counters */ pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL, @@ -504,14 +461,35 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) | (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48); - for (i = 0; i < ARRAY_SIZE(hw_stats); i++) { - unsigned reg = p->reg - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW; - - pm3393_rmon_update((mac)->adapter, OFFSET(p->reg), - stats + p->offset, ro & (reg >> 2)); - } - - + /* Rx stats */ + RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK); + RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK); + RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK); + RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK); + RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames); + RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors); + RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors, + RxInternalMACRcvError); + RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors); + RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors); + RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors); + RMON_UPDATE(mac, RxJabbers, RxJabberErrors); + RMON_UPDATE(mac, RxFragments, RxRuntErrors); + RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors); + RMON_UPDATE(mac, RxJumboFramesReceivedOK, RxJumboFramesOK); + RMON_UPDATE(mac, RxJumboOctetsReceivedOK, RxJumboOctetsOK); + + /* Tx stats */ + RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK); + RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError, + TxInternalMACXmitError); + RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors); + RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK); + RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK); + RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK); + RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames); + RMON_UPDATE(mac, TxJumboFramesReceivedOK, TxJumboFramesOK); + RMON_UPDATE(mac, TxJumboOctetsReceivedOK, TxJumboOctetsOK); return &mac->stats; } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index ffa7e649a6e..8a7efd38e95 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -330,6 +330,8 @@ unsigned int t1_sched_update_parms(struct sge *sge, unsigned int port, return max_avail_segs * (p->mtu - 40); } +#if 0 + /* * t1_sched_max_avail_bytes() tells the scheduler the maximum amount of * data that can be pushed per port. @@ -357,6 +359,8 @@ void t1_sched_set_drain_bits_per_us(struct sge *sge, unsigned int port, t1_sched_update_parms(sge, port, 0, 0); } +#endif /* 0 */ + /* * get_clock() implements a ns clock (see ktime_get) @@ -986,11 +990,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; } @@ -1379,11 +1382,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) } __skb_pull(skb, sizeof(*p)); - skb->dev->last_rx = jiffies; 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; if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff && skb->protocol == htons(ETH_P_IP) && (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) { @@ -1624,11 +1626,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; + int work_done = process_responses(adapter, budget); - 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 +1848,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 +1857,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 +1902,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 +1947,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); diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h index 713d9c55f24..8c940512399 100644 --- a/drivers/net/chelsio/sge.h +++ b/drivers/net/chelsio/sge.h @@ -57,13 +57,12 @@ struct sge_intr_counts { }; struct sge_port_stats { - u64 rx_packets; /* # of Ethernet packets received */ u64 rx_cso_good; /* # of successful RX csum offloads */ - u64 tx_packets; /* # of TX packets */ u64 tx_cso; /* # of TX checksum offloads */ u64 tx_tso; /* # of TSO requests */ u64 vlan_xtract; /* # of VLAN tag extractions */ u64 vlan_insert; /* # of VLAN tag insertions */ + u64 tx_need_hdrroom; /* # of TX skbs in need of more header room */ }; struct sk_buff; @@ -89,8 +88,6 @@ void t1_sge_intr_disable(struct sge *); void t1_sge_intr_clear(struct sge *); const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge); void t1_sge_get_port_stats(const struct sge *sge, int port, struct sge_port_stats *); -void t1_sched_set_max_avail_bytes(struct sge *, unsigned int); -void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int); unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int, unsigned int); diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index dc50151bed8..7adf30230c4 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -563,10 +563,11 @@ struct chelsio_vpd_t { * written to the Control register. The hardware device will set the flag to a * one when 4B have been transferred to the Data register. */ -int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data) +int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data) { int i = EEPROM_MAX_POLL; u16 val; + u32 v; if (addr >= EEPROMSIZE || (addr & 3)) return -EINVAL; @@ -582,8 +583,8 @@ int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data) adapter->name, addr); return -EIO; } - pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data); - *data = le32_to_cpu(*data); + pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v); + *data = cpu_to_le32(v); return 0; } @@ -593,7 +594,7 @@ static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd) for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32)) ret = t1_seeprom_read(adapter, addr, - (u32 *)((u8 *)vpd + addr)); + (__le32 *)((u8 *)vpd + addr)); return ret; } |