diff options
Diffstat (limited to 'drivers/net/cxgb4/sge.c')
-rw-r--r-- | drivers/net/cxgb4/sge.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index bf38cfc57565..56adf448b9fe 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/ip.h> | 39 | #include <linux/ip.h> |
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/jiffies.h> | 41 | #include <linux/jiffies.h> |
42 | #include <linux/prefetch.h> | ||
42 | #include <net/ipv6.h> | 43 | #include <net/ipv6.h> |
43 | #include <net/tcp.h> | 44 | #include <net/tcp.h> |
44 | #include "cxgb4.h" | 45 | #include "cxgb4.h" |
@@ -557,7 +558,8 @@ out: cred = q->avail - cred; | |||
557 | 558 | ||
558 | if (unlikely(fl_starving(q))) { | 559 | if (unlikely(fl_starving(q))) { |
559 | smp_wmb(); | 560 | smp_wmb(); |
560 | set_bit(q->cntxt_id, adap->sge.starving_fl); | 561 | set_bit(q->cntxt_id - adap->sge.egr_start, |
562 | adap->sge.starving_fl); | ||
561 | } | 563 | } |
562 | 564 | ||
563 | return cred; | 565 | return cred; |
@@ -578,6 +580,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) | |||
578 | * @phys: the physical address of the allocated ring | 580 | * @phys: the physical address of the allocated ring |
579 | * @metadata: address of the array holding the SW state for the ring | 581 | * @metadata: address of the array holding the SW state for the ring |
580 | * @stat_size: extra space in HW ring for status information | 582 | * @stat_size: extra space in HW ring for status information |
583 | * @node: preferred node for memory allocations | ||
581 | * | 584 | * |
582 | * Allocates resources for an SGE descriptor ring, such as Tx queues, | 585 | * Allocates resources for an SGE descriptor ring, such as Tx queues, |
583 | * free buffer lists, or response queues. Each SGE ring requires | 586 | * free buffer lists, or response queues. Each SGE ring requires |
@@ -589,7 +592,7 @@ static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) | |||
589 | */ | 592 | */ |
590 | static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, | 593 | static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, |
591 | size_t sw_size, dma_addr_t *phys, void *metadata, | 594 | size_t sw_size, dma_addr_t *phys, void *metadata, |
592 | size_t stat_size) | 595 | size_t stat_size, int node) |
593 | { | 596 | { |
594 | size_t len = nelem * elem_size + stat_size; | 597 | size_t len = nelem * elem_size + stat_size; |
595 | void *s = NULL; | 598 | void *s = NULL; |
@@ -598,7 +601,7 @@ static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, | |||
598 | if (!p) | 601 | if (!p) |
599 | return NULL; | 602 | return NULL; |
600 | if (sw_size) { | 603 | if (sw_size) { |
601 | s = kcalloc(nelem, sw_size, GFP_KERNEL); | 604 | s = kzalloc_node(nelem * sw_size, GFP_KERNEL, node); |
602 | 605 | ||
603 | if (!s) { | 606 | if (!s) { |
604 | dma_free_coherent(dev, len, p, *phys); | 607 | dma_free_coherent(dev, len, p, *phys); |
@@ -974,7 +977,7 @@ out_free: dev_kfree_skb(skb); | |||
974 | } | 977 | } |
975 | 978 | ||
976 | cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | | 979 | cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | |
977 | TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0)); | 980 | TXPKT_INTF(pi->tx_chan) | TXPKT_PF(adap->fn)); |
978 | cpl->pack = htons(0); | 981 | cpl->pack = htons(0); |
979 | cpl->len = htons(skb->len); | 982 | cpl->len = htons(skb->len); |
980 | cpl->ctrl1 = cpu_to_be64(cntrl); | 983 | cpl->ctrl1 = cpu_to_be64(cntrl); |
@@ -1213,7 +1216,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q) | |||
1213 | { | 1216 | { |
1214 | q->mapping_err++; | 1217 | q->mapping_err++; |
1215 | q->q.stops++; | 1218 | q->q.stops++; |
1216 | set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr); | 1219 | set_bit(q->q.cntxt_id - q->adap->sge.egr_start, |
1220 | q->adap->sge.txq_maperr); | ||
1217 | } | 1221 | } |
1218 | 1222 | ||
1219 | /** | 1223 | /** |
@@ -1528,18 +1532,11 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl, | |||
1528 | skb->rxhash = (__force u32)pkt->rsshdr.hash_val; | 1532 | skb->rxhash = (__force u32)pkt->rsshdr.hash_val; |
1529 | 1533 | ||
1530 | if (unlikely(pkt->vlan_ex)) { | 1534 | if (unlikely(pkt->vlan_ex)) { |
1531 | struct port_info *pi = netdev_priv(rxq->rspq.netdev); | 1535 | __vlan_hwaccel_put_tag(skb, ntohs(pkt->vlan)); |
1532 | struct vlan_group *grp = pi->vlan_grp; | ||
1533 | |||
1534 | rxq->stats.vlan_ex++; | 1536 | rxq->stats.vlan_ex++; |
1535 | if (likely(grp)) { | ||
1536 | ret = vlan_gro_frags(&rxq->rspq.napi, grp, | ||
1537 | ntohs(pkt->vlan)); | ||
1538 | goto stats; | ||
1539 | } | ||
1540 | } | 1537 | } |
1541 | ret = napi_gro_frags(&rxq->rspq.napi); | 1538 | ret = napi_gro_frags(&rxq->rspq.napi); |
1542 | stats: if (ret == GRO_HELD) | 1539 | if (ret == GRO_HELD) |
1543 | rxq->stats.lro_pkts++; | 1540 | rxq->stats.lro_pkts++; |
1544 | else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE) | 1541 | else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE) |
1545 | rxq->stats.lro_merged++; | 1542 | rxq->stats.lro_merged++; |
@@ -1560,7 +1557,6 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | |||
1560 | { | 1557 | { |
1561 | bool csum_ok; | 1558 | bool csum_ok; |
1562 | struct sk_buff *skb; | 1559 | struct sk_buff *skb; |
1563 | struct port_info *pi; | ||
1564 | const struct cpl_rx_pkt *pkt; | 1560 | const struct cpl_rx_pkt *pkt; |
1565 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); | 1561 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); |
1566 | 1562 | ||
@@ -1588,10 +1584,9 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | |||
1588 | if (skb->dev->features & NETIF_F_RXHASH) | 1584 | if (skb->dev->features & NETIF_F_RXHASH) |
1589 | skb->rxhash = (__force u32)pkt->rsshdr.hash_val; | 1585 | skb->rxhash = (__force u32)pkt->rsshdr.hash_val; |
1590 | 1586 | ||
1591 | pi = netdev_priv(skb->dev); | ||
1592 | rxq->stats.pkts++; | 1587 | rxq->stats.pkts++; |
1593 | 1588 | ||
1594 | if (csum_ok && (pi->rx_offload & RX_CSO) && | 1589 | if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) && |
1595 | (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) { | 1590 | (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) { |
1596 | if (!pkt->ip_frag) { | 1591 | if (!pkt->ip_frag) { |
1597 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1592 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -1603,19 +1598,13 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | |||
1603 | rxq->stats.rx_cso++; | 1598 | rxq->stats.rx_cso++; |
1604 | } | 1599 | } |
1605 | } else | 1600 | } else |
1606 | skb->ip_summed = CHECKSUM_NONE; | 1601 | skb_checksum_none_assert(skb); |
1607 | 1602 | ||
1608 | if (unlikely(pkt->vlan_ex)) { | 1603 | if (unlikely(pkt->vlan_ex)) { |
1609 | struct vlan_group *grp = pi->vlan_grp; | 1604 | __vlan_hwaccel_put_tag(skb, ntohs(pkt->vlan)); |
1610 | |||
1611 | rxq->stats.vlan_ex++; | 1605 | rxq->stats.vlan_ex++; |
1612 | if (likely(grp)) | 1606 | } |
1613 | vlan_hwaccel_receive_skb(skb, grp, ntohs(pkt->vlan)); | 1607 | netif_receive_skb(skb); |
1614 | else | ||
1615 | dev_kfree_skb_any(skb); | ||
1616 | } else | ||
1617 | netif_receive_skb(skb); | ||
1618 | |||
1619 | return 0; | 1608 | return 0; |
1620 | } | 1609 | } |
1621 | 1610 | ||
@@ -1835,6 +1824,7 @@ static unsigned int process_intrq(struct adapter *adap) | |||
1835 | if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { | 1824 | if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { |
1836 | unsigned int qid = ntohl(rc->pldbuflen_qid); | 1825 | unsigned int qid = ntohl(rc->pldbuflen_qid); |
1837 | 1826 | ||
1827 | qid -= adap->sge.ingr_start; | ||
1838 | napi_schedule(&adap->sge.ingr_map[qid]->napi); | 1828 | napi_schedule(&adap->sge.ingr_map[qid]->napi); |
1839 | } | 1829 | } |
1840 | 1830 | ||
@@ -1992,7 +1982,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, | |||
1992 | iq->size = roundup(iq->size, 16); | 1982 | iq->size = roundup(iq->size, 16); |
1993 | 1983 | ||
1994 | iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0, | 1984 | iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0, |
1995 | &iq->phys_addr, NULL, 0); | 1985 | &iq->phys_addr, NULL, 0, NUMA_NO_NODE); |
1996 | if (!iq->desc) | 1986 | if (!iq->desc) |
1997 | return -ENOMEM; | 1987 | return -ENOMEM; |
1998 | 1988 | ||
@@ -2018,12 +2008,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, | |||
2018 | fl->size = roundup(fl->size, 8); | 2008 | fl->size = roundup(fl->size, 8); |
2019 | fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64), | 2009 | fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64), |
2020 | sizeof(struct rx_sw_desc), &fl->addr, | 2010 | sizeof(struct rx_sw_desc), &fl->addr, |
2021 | &fl->sdesc, STAT_LEN); | 2011 | &fl->sdesc, STAT_LEN, NUMA_NO_NODE); |
2022 | if (!fl->desc) | 2012 | if (!fl->desc) |
2023 | goto fl_nomem; | 2013 | goto fl_nomem; |
2024 | 2014 | ||
2025 | flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc); | 2015 | flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc); |
2026 | c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN | | 2016 | c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN | |
2017 | FW_IQ_CMD_FL0FETCHRO(1) | | ||
2018 | FW_IQ_CMD_FL0DATARO(1) | | ||
2027 | FW_IQ_CMD_FL0PADEN); | 2019 | FW_IQ_CMD_FL0PADEN); |
2028 | c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) | | 2020 | c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) | |
2029 | FW_IQ_CMD_FL0FBMAX(3)); | 2021 | FW_IQ_CMD_FL0FBMAX(3)); |
@@ -2050,14 +2042,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, | |||
2050 | /* set offset to -1 to distinguish ingress queues without FL */ | 2042 | /* set offset to -1 to distinguish ingress queues without FL */ |
2051 | iq->offset = fl ? 0 : -1; | 2043 | iq->offset = fl ? 0 : -1; |
2052 | 2044 | ||
2053 | adap->sge.ingr_map[iq->cntxt_id] = iq; | 2045 | adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq; |
2054 | 2046 | ||
2055 | if (fl) { | 2047 | if (fl) { |
2056 | fl->cntxt_id = ntohs(c.fl0id); | 2048 | fl->cntxt_id = ntohs(c.fl0id); |
2057 | fl->avail = fl->pend_cred = 0; | 2049 | fl->avail = fl->pend_cred = 0; |
2058 | fl->pidx = fl->cidx = 0; | 2050 | fl->pidx = fl->cidx = 0; |
2059 | fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; | 2051 | fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; |
2060 | adap->sge.egr_map[fl->cntxt_id] = fl; | 2052 | adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl; |
2061 | refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); | 2053 | refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); |
2062 | } | 2054 | } |
2063 | return 0; | 2055 | return 0; |
@@ -2087,7 +2079,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) | |||
2087 | q->stops = q->restarts = 0; | 2079 | q->stops = q->restarts = 0; |
2088 | q->stat = (void *)&q->desc[q->size]; | 2080 | q->stat = (void *)&q->desc[q->size]; |
2089 | q->cntxt_id = id; | 2081 | q->cntxt_id = id; |
2090 | adap->sge.egr_map[id] = q; | 2082 | adap->sge.egr_map[id - adap->sge.egr_start] = q; |
2091 | } | 2083 | } |
2092 | 2084 | ||
2093 | int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | 2085 | int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, |
@@ -2103,7 +2095,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | |||
2103 | 2095 | ||
2104 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, | 2096 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, |
2105 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), | 2097 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), |
2106 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); | 2098 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN, |
2099 | netdev_queue_numa_node_read(netdevq)); | ||
2107 | if (!txq->q.desc) | 2100 | if (!txq->q.desc) |
2108 | return -ENOMEM; | 2101 | return -ENOMEM; |
2109 | 2102 | ||
@@ -2116,6 +2109,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | |||
2116 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); | 2109 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); |
2117 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | | 2110 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | |
2118 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | | 2111 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | |
2112 | FW_EQ_ETH_CMD_FETCHRO(1) | | ||
2119 | FW_EQ_ETH_CMD_IQID(iqid)); | 2113 | FW_EQ_ETH_CMD_IQID(iqid)); |
2120 | c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) | | 2114 | c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) | |
2121 | FW_EQ_ETH_CMD_FBMAX(3) | | 2115 | FW_EQ_ETH_CMD_FBMAX(3) | |
@@ -2154,7 +2148,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, | |||
2154 | 2148 | ||
2155 | txq->q.desc = alloc_ring(adap->pdev_dev, nentries, | 2149 | txq->q.desc = alloc_ring(adap->pdev_dev, nentries, |
2156 | sizeof(struct tx_desc), 0, &txq->q.phys_addr, | 2150 | sizeof(struct tx_desc), 0, &txq->q.phys_addr, |
2157 | NULL, 0); | 2151 | NULL, 0, NUMA_NO_NODE); |
2158 | if (!txq->q.desc) | 2152 | if (!txq->q.desc) |
2159 | return -ENOMEM; | 2153 | return -ENOMEM; |
2160 | 2154 | ||
@@ -2168,6 +2162,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, | |||
2168 | c.physeqid_pkd = htonl(0); | 2162 | c.physeqid_pkd = htonl(0); |
2169 | c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) | | 2163 | c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) | |
2170 | FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) | | 2164 | FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) | |
2165 | FW_EQ_CTRL_CMD_FETCHRO | | ||
2171 | FW_EQ_CTRL_CMD_IQID(iqid)); | 2166 | FW_EQ_CTRL_CMD_IQID(iqid)); |
2172 | c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) | | 2167 | c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) | |
2173 | FW_EQ_CTRL_CMD_FBMAX(3) | | 2168 | FW_EQ_CTRL_CMD_FBMAX(3) | |
@@ -2204,7 +2199,8 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, | |||
2204 | 2199 | ||
2205 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, | 2200 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, |
2206 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), | 2201 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), |
2207 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); | 2202 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN, |
2203 | NUMA_NO_NODE); | ||
2208 | if (!txq->q.desc) | 2204 | if (!txq->q.desc) |
2209 | return -ENOMEM; | 2205 | return -ENOMEM; |
2210 | 2206 | ||
@@ -2217,6 +2213,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, | |||
2217 | FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); | 2213 | FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); |
2218 | c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | | 2214 | c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | |
2219 | FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) | | 2215 | FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) | |
2216 | FW_EQ_OFLD_CMD_FETCHRO(1) | | ||
2220 | FW_EQ_OFLD_CMD_IQID(iqid)); | 2217 | FW_EQ_OFLD_CMD_IQID(iqid)); |
2221 | c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) | | 2218 | c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) | |
2222 | FW_EQ_OFLD_CMD_FBMAX(3) | | 2219 | FW_EQ_OFLD_CMD_FBMAX(3) | |
@@ -2259,7 +2256,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, | |||
2259 | { | 2256 | { |
2260 | unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; | 2257 | unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; |
2261 | 2258 | ||
2262 | adap->sge.ingr_map[rq->cntxt_id] = NULL; | 2259 | adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL; |
2263 | t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, | 2260 | t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, |
2264 | rq->cntxt_id, fl_id, 0xffff); | 2261 | rq->cntxt_id, fl_id, 0xffff); |
2265 | dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, | 2262 | dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, |