Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci ixl(4) supports ETHERCAP_VLAN_HWTAGGING
details: https://anonhg.NetBSD.org/src/rev/5a6814112686
branches: trunk
changeset: 466393:5a6814112686
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Fri Dec 20 02:12:31 2019 +0000
description:
ixl(4) supports ETHERCAP_VLAN_HWTAGGING
It is enabled by defualt
The features is realized by the following operations:
- internal switch
- use "0b00: Show VLAN, DEI and UP in descriptor" mode
- TX
- set VLAN tag and IL2TAG1 flag to each descriptor
- RX
- use 32byte descriptor to use SHOWIV and L2SEL flag
included in RX queue configuration
- VLAN tags are not stored in descriptor without these config.
- get VLAN tags from L2TAG1 field included in RX descriptor
and set them to mbuf
reviewed by msaitoh and knakahara
diffstat:
sys/dev/pci/if_ixl.c | 106 ++++++++++++++++++++++++++++++++++-------------
sys/dev/pci/if_ixlvar.h | 5 +-
2 files changed, 80 insertions(+), 31 deletions(-)
diffs (287 lines):
diff -r 76ea9e9a19d8 -r 5a6814112686 sys/dev/pci/if_ixl.c
--- a/sys/dev/pci/if_ixl.c Fri Dec 20 02:04:26 2019 +0000
+++ b/sys/dev/pci/if_ixl.c Fri Dec 20 02:12:31 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ixl.c,v 1.10 2019/12/20 02:04:26 yamaguchi Exp $ */
+/* $NetBSD: if_ixl.c,v 1.11 2019/12/20 02:12:31 yamaguchi Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -525,6 +525,8 @@
u_int sc_tx_intr_process_limit;
u_int sc_rx_intr_process_limit;
+ int sc_cur_ec_capenable;
+
struct pci_attach_args sc_pa;
pci_intr_handle_t *sc_ihp;
void **sc_ihs;
@@ -1125,13 +1127,17 @@
goto free_hmc;
}
- if (ixl_get_vsi(sc) != 0) {
- /* error printed by ixl_get_vsi */
+ rv = ixl_get_vsi(sc);
+ if (rv != 0) {
+ aprint_error_dev(self, "GET VSI %s %d\n",
+ rv == ETIMEDOUT ? "timeout" : "error", rv);
goto free_scratch;
}
- if (ixl_set_vsi(sc) != 0) {
- /* error printed by ixl_set_vsi */
+ rv = ixl_set_vsi(sc);
+ if (rv != 0) {
+ aprint_error_dev(self, "UPDATE VSI error %s %d\n",
+ rv == ETIMEDOUT ? "timeout" : "error", rv);
goto free_scratch;
}
@@ -1189,9 +1195,10 @@
IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx;
#endif
sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
-#if 0
sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
-#endif
+
+ sc->sc_ec.ec_capenable = sc->sc_ec.ec_capabilities;
+ sc->sc_cur_ec_capenable = sc->sc_ec.ec_capenable;
sc->sc_ec.ec_ifmedia = &sc->sc_media;
ifmedia_init(&sc->sc_media, IFM_IMASK, ixl_media_change,
@@ -1713,6 +1720,13 @@
KASSERT(mutex_owned(&sc->sc_cfg_lock));
+ if (ixl_get_vsi(sc) != 0)
+ return EIO;
+
+ if (ixl_set_vsi(sc) != 0)
+ return EIO;
+
+
for (i = 0; i < sc->sc_nqueue_pairs; i++) {
txr = sc->sc_qps[i].qp_txr;
rxr = sc->sc_qps[i].qp_rxr;
@@ -1781,10 +1795,15 @@
KASSERT(mutex_owned(&sc->sc_cfg_lock));
+ if (ISSET(ifp->if_flags, IFF_RUNNING))
+ ixl_stop_locked(sc);
+
if (sc->sc_dead) {
return ENXIO;
}
+ sc->sc_cur_ec_capenable = sc->sc_ec.ec_capenable;
+
if (sc->sc_intrtype != PCI_INTR_TYPE_MSIX)
sc->sc_nqueue_pairs = 1;
else
@@ -2304,7 +2323,7 @@
struct ixl_tx_map *txm;
bus_dmamap_t map;
struct mbuf *m;
- uint64_t cmd;
+ uint64_t cmd, cmd_vlan;
unsigned int prod, free, last, i;
unsigned int mask;
int post = 0;
@@ -2358,6 +2377,14 @@
continue;
}
+ if (vlan_has_tag(m)) {
+ cmd_vlan = (uint64_t)vlan_get_tag(m) <<
+ IXL_TX_DESC_L2TAG1_SHIFT;
+ cmd_vlan |= IXL_TX_DESC_CMD_IL2TAG1;
+ } else {
+ cmd_vlan = 0;
+ }
+
bus_dmamap_sync(sc->sc_dmat, map, 0,
map->dm_mapsize, BUS_DMASYNC_PREWRITE);
@@ -2367,6 +2394,7 @@
cmd = (uint64_t)map->dm_segs[i].ds_len <<
IXL_TX_DESC_BSIZE_SHIFT;
cmd |= IXL_TX_DESC_DTYPE_DATA | IXL_TX_DESC_CMD_ICRC;
+ cmd |= cmd_vlan;
txd->addr = htole64(map->dm_segs[i].ds_addr);
txd->cmd = htole64(cmd);
@@ -2558,7 +2586,7 @@
KM_SLEEP);
if (ixl_dmamem_alloc(sc, &rxr->rxr_mem,
- sizeof(struct ixl_rx_rd_desc_16) * sc->sc_rx_ring_ndescs,
+ sizeof(struct ixl_rx_rd_desc_32) * sc->sc_rx_ring_ndescs,
IXL_RX_QUEUE_ALIGN) != 0)
goto free;
@@ -2684,10 +2712,10 @@
rxq.dbuff = htole16(MCLBYTES / IXL_HMC_RXQ_DBUFF_UNIT);
rxq.hbuff = 0;
rxq.dtype = IXL_HMC_RXQ_DTYPE_NOSPLIT;
- rxq.dsize = IXL_HMC_RXQ_DSIZE_16;
+ rxq.dsize = IXL_HMC_RXQ_DSIZE_32;
rxq.crcstrip = 1;
- rxq.l2sel = 0;
- rxq.showiv = 0;
+ rxq.l2sel = 1;
+ rxq.showiv = 1;
rxq.rxmax = htole16(IXL_HARDMTU);
rxq.tphrdesc_ena = 0;
rxq.tphwdesc_ena = 0;
@@ -2734,12 +2762,12 @@
ixl_rxeof(struct ixl_softc *sc, struct ixl_rx_ring *rxr, u_int rxlimit)
{
struct ifnet *ifp = &sc->sc_ec.ec_if;
- struct ixl_rx_wb_desc_16 *ring, *rxd;
+ struct ixl_rx_wb_desc_32 *ring, *rxd;
struct ixl_rx_map *rxm;
bus_dmamap_t map;
unsigned int cons, prod;
struct mbuf *m;
- uint64_t word;
+ uint64_t word, word0;
unsigned int len;
unsigned int mask;
int done = 0, more = 0;
@@ -2799,6 +2827,13 @@
m->m_pkthdr.len += len;
if (ISSET(word, IXL_RX_DESC_EOP)) {
+ word0 = le64toh(rxd->qword0);
+
+ if (ISSET(word, IXL_RX_DESC_L2TAG1P)) {
+ vlan_set_tag(m,
+ __SHIFTOUT(word0, IXL_RX_DESC_L2TAG1_MASK));
+ }
+
if (!ISSET(word,
IXL_RX_DESC_RXE | IXL_RX_DESC_OVERSIZE)) {
m_set_rcvif(m, ifp);
@@ -2836,7 +2871,7 @@
static int
ixl_rxfill(struct ixl_softc *sc, struct ixl_rx_ring *rxr)
{
- struct ixl_rx_rd_desc_16 *ring, *rxd;
+ struct ixl_rx_rd_desc_32 *ring, *rxd;
struct ixl_rx_map *rxm;
bus_dmamap_t map;
struct mbuf *m;
@@ -3921,14 +3956,11 @@
BUS_DMASYNC_POSTREAD);
if (rv != 0) {
- aprint_error_dev(sc->sc_dev, "GET VSI timeout\n");
- return -1;
+ return ETIMEDOUT;
}
if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
- aprint_error_dev(sc->sc_dev, "GET VSI error %u\n",
- le16toh(iaq.iaq_retval));
- return -1;
+ return EIO;
}
reply = (struct ixl_aq_vsi_reply *)iaq.iaq_param;
@@ -3945,6 +3977,7 @@
struct ixl_aq_vsi_param *param;
struct ixl_aq_vsi_data *data = IXL_DMA_KVA(vsi);
unsigned int qnum;
+ uint16_t val;
int rv;
qnum = sc->sc_nqueue_pairs - 1;
@@ -3958,10 +3991,17 @@
data->tc_mapping[0] = htole16((0 << IXL_AQ_VSI_TC_Q_OFFSET_SHIFT) |
(qnum << IXL_AQ_VSI_TC_Q_NUMBER_SHIFT));
- CLR(data->port_vlan_flags,
- htole16(IXL_AQ_VSI_PVLAN_MODE_MASK | IXL_AQ_VSI_PVLAN_EMOD_MASK));
- SET(data->port_vlan_flags,
- htole16(IXL_AQ_VSI_PVLAN_MODE_ALL | IXL_AQ_VSI_PVLAN_EMOD_NOTHING));
+ val = le16toh(data->port_vlan_flags);
+ CLR(val, IXL_AQ_VSI_PVLAN_MODE_MASK | IXL_AQ_VSI_PVLAN_EMOD_MASK);
+ SET(val, IXL_AQ_VSI_PVLAN_MODE_ALL);
+
+ if (ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWTAGGING)) {
+ SET(val, IXL_AQ_VSI_PVLAN_EMOD_STR_BOTH);
+ } else {
+ SET(val, IXL_AQ_VSI_PVLAN_EMOD_NOTHING);
+ }
+
+ data->port_vlan_flags = htole16(val);
/* grumble, vsi info isn't "known" at compile time */
@@ -3984,14 +4024,11 @@
BUS_DMASYNC_POSTWRITE);
if (rv != 0) {
- aprint_error_dev(sc->sc_dev, "UPDATE VSI timeout\n");
- return -1;
+ return ETIMEDOUT;
}
if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) {
- aprint_error_dev(sc->sc_dev, "UPDATE VSI error %u\n",
- le16toh(iaq.iaq_retval));
- return -1;
+ return EIO;
}
return 0;
@@ -4827,10 +4864,19 @@
{
struct ifnet *ifp = &ec->ec_if;
struct ixl_softc *sc = ifp->if_softc;
- int rv;
+ int rv, change;
mutex_enter(&sc->sc_cfg_lock);
+
+ change = ec->ec_capenable ^ sc->sc_cur_ec_capenable;
+
+ if (ISSET(change, ETHERCAP_VLAN_HWTAGGING)) {
+ rv = ENETRESET;
+ goto out;
+ }
+
rv = ixl_iff(sc);
+out:
mutex_exit(&sc->sc_cfg_lock);
return rv;
diff -r 76ea9e9a19d8 -r 5a6814112686 sys/dev/pci/if_ixlvar.h
--- a/sys/dev/pci/if_ixlvar.h Fri Dec 20 02:04:26 2019 +0000
+++ b/sys/dev/pci/if_ixlvar.h Fri Dec 20 02:12:31 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ixlvar.h,v 1.1 2019/12/10 12:08:52 yamaguchi Exp $ */
+/* $NetBSD: if_ixlvar.h,v 1.2 2019/12/20 02:12:31 yamaguchi Exp $ */
/*
* Copyright (c) 2019 Internet Initiative Japan, Inc.
@@ -729,6 +729,7 @@
#define IXL_TX_DESC_BSIZE_MAX 0x3fffULL
#define IXL_TX_DESC_BSIZE_MASK \
(IXL_TX_DESC_BSIZE_MAX << IXL_TX_DESC_BSIZE_SHIFT)
+#define IXL_TX_DESC_L2TAG1_SHIFT 48
} __packed __aligned(16);
struct ixl_rx_rd_desc_16 {
@@ -745,6 +746,8 @@
struct ixl_rx_wb_desc_16 {
uint64_t qword0;
+#define IXL_RX_DESC_L2TAG1_SHIFT 16
+#define IXL_RX_DESC_L2TAG1_MASK (0xffffULL << IXL_RX_DESC_L2TAG1_SHIFT)
uint64_t qword1;
#define IXL_RX_DESC_DD (1 << 0)
#define IXL_RX_DESC_EOP (1 << 1)
Home |
Main Index |
Thread Index |
Old Index