diff options
| author | Navdeep Parhar <np@FreeBSD.org> | 2012-10-15 06:41:54 +0000 |
|---|---|---|
| committer | Navdeep Parhar <np@FreeBSD.org> | 2012-10-15 06:41:54 +0000 |
| commit | 90a4c8e15898294839383605546ef2e60cdb9770 (patch) | |
| tree | 82abbde8bb4618f7958f3c0d8502c669c3eaed92 /sys/dev/cxgbe | |
| parent | 5dd669d5714c6865dfed8358ca90ad59c149f92d (diff) | |
Notes
Diffstat (limited to 'sys/dev/cxgbe')
| -rw-r--r-- | sys/dev/cxgbe/adapter.h | 1 | ||||
| -rw-r--r-- | sys/dev/cxgbe/common/common.h | 2 | ||||
| -rw-r--r-- | sys/dev/cxgbe/common/t4_hw.c | 30 | ||||
| -rw-r--r-- | sys/dev/cxgbe/t4_ioctl.h | 12 | ||||
| -rw-r--r-- | sys/dev/cxgbe/t4_main.c | 42 | ||||
| -rw-r--r-- | sys/dev/cxgbe/t4_sge.c | 33 |
6 files changed, 93 insertions, 27 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 71f0fe9329f8..9320273427d9 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -282,7 +282,6 @@ struct sge_iq { bus_dma_tag_t desc_tag; bus_dmamap_t desc_map; bus_addr_t ba; /* bus address of descriptor ring */ - char lockname[16]; uint32_t flags; uint16_t abs_id; /* absolute SGE id for the iq */ int8_t intr_pktc_idx; /* packet count threshold index */ diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index f61a8d724411..54647eaeaf17 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -521,6 +521,8 @@ int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid, bool rx_en, bool tx_en); int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, unsigned int nblinks); +int t4_i2c_rd(struct adapter *adap, unsigned int mbox, unsigned int port_id, + u8 dev_addr, u8 offset, u8 *valp); int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, unsigned int *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 8cdcfe30d877..902a4e85c6be 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -3885,6 +3885,36 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, u32 addr, u32 } /** + * t4_i2c_rd - read a byte from an i2c addressable device + * @adap: the adapter + * @mbox: mailbox to use for the FW command + * @port_id: the port id + * @dev_addr: the i2c device address + * @offset: the byte offset to read from + * @valp: where to store the value + */ +int t4_i2c_rd(struct adapter *adap, unsigned int mbox, unsigned int port_id, + u8 dev_addr, u8 offset, u8 *valp) +{ + int ret; + struct fw_ldst_cmd c; + + memset(&c, 0, sizeof(c)); + c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST | + F_FW_CMD_READ | + V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_I2C)); + c.cycles_to_len16 = htonl(FW_LEN16(c)); + c.u.i2c.pid_pkd = V_FW_LDST_CMD_PID(port_id); + c.u.i2c.base = dev_addr; + c.u.i2c.boffset = offset; + + ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); + if (ret == 0) + *valp = c.u.i2c.data; + return ret; +} + +/** * t4_mdio_rd - read a PHY register through MDIO * @adap: the adapter * @mbox: mailbox to use for the FW command diff --git a/sys/dev/cxgbe/t4_ioctl.h b/sys/dev/cxgbe/t4_ioctl.h index 2a3fa3998ef1..4a55c116fdda 100644 --- a/sys/dev/cxgbe/t4_ioctl.h +++ b/sys/dev/cxgbe/t4_ioctl.h @@ -49,6 +49,8 @@ enum { T4_GET_SGE_CONTEXT, /* get SGE context for a queue */ T4_LOAD_FW, /* flash firmware */ T4_GET_MEM, /* read memory */ + T4_GET_I2C, /* read from i2c addressible device */ + T4_CLEAR_STATS, /* clear a port's MAC statistics */ }; struct t4_reg { @@ -69,6 +71,14 @@ struct t4_data { uint8_t *data; }; +struct t4_i2c_data { + uint8_t port_id; + uint8_t dev_addr; + uint8_t offset; + uint8_t len; + uint8_t data[8]; +}; + /* * A hardware filter is some valid combination of these. */ @@ -224,4 +234,6 @@ struct t4_mem_range { struct t4_sge_context) #define CHELSIO_T4_LOAD_FW _IOW('f', T4_LOAD_FW, struct t4_data) #define CHELSIO_T4_GET_MEM _IOW('f', T4_GET_MEM, struct t4_mem_range) +#define CHELSIO_T4_GET_I2C _IOWR('f', T4_GET_I2C, struct t4_i2c_data) +#define CHELSIO_T4_CLEAR_STATS _IOW('f', T4_CLEAR_STATS, uint32_t) #endif diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 5b46e142519c..ff5c116dd359 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -349,6 +349,7 @@ static int set_filter_wr(struct adapter *, int); static int del_filter_wr(struct adapter *, int); static int get_sge_context(struct adapter *, struct t4_sge_context *); static int read_card_mem(struct adapter *, struct t4_mem_range *); +static int read_i2c(struct adapter *, struct t4_i2c_data *); #ifdef TCP_OFFLOAD static int toe_capability(struct port_info *, int); #endif @@ -526,10 +527,6 @@ t4_attach(device_t dev) t4_write_reg(sc, A_ULP_RX_TDDP_PSZ, V_HPZ0(0) | V_HPZ1(2) | V_HPZ2(4) | V_HPZ3(6)); t4_set_reg_field(sc, A_ULP_RX_CTL, F_TDDPTAGTCB, F_TDDPTAGTCB); - t4_set_reg_field(sc, A_TP_PARA_REG3, F_TUNNELCNGDROP0 | - F_TUNNELCNGDROP1 | F_TUNNELCNGDROP2 | F_TUNNELCNGDROP3, - F_TUNNELCNGDROP0 | F_TUNNELCNGDROP1 | F_TUNNELCNGDROP2 | - F_TUNNELCNGDROP3); t4_set_reg_field(sc, A_TP_PARA_REG5, V_INDICATESIZE(M_INDICATESIZE) | F_REARMDDPOFFSET | F_RESETDDPOFFSET, @@ -2995,7 +2992,7 @@ cxgbe_vlan_config(void *arg, struct ifnet *ifp, uint16_t vid) { struct ifnet *vlan; - if (arg != ifp) + if (arg != ifp || ifp->if_type != IFT_ETHER) return; vlan = VLAN_DEVAT(ifp, vid); @@ -5170,6 +5167,27 @@ proceed: return (rc); } +static int +read_i2c(struct adapter *sc, struct t4_i2c_data *i2cd) +{ + int rc; + + ADAPTER_LOCK_ASSERT_OWNED(sc); /* for mbox */ + + if (i2cd->len == 0 || i2cd->port_id >= sc->params.nports) + return (EINVAL); + + if (i2cd->len > 1) { + /* XXX: need fw support for longer reads in one go */ + return (ENOTSUP); + } + + rc = -t4_i2c_rd(sc, sc->mbox, i2cd->port_id, i2cd->dev_addr, + i2cd->offset, &i2cd->data[0]); + + return (rc); +} + int t4_os_find_pci_capability(struct adapter *sc, int cap) { @@ -5373,6 +5391,20 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag, case CHELSIO_T4_GET_MEM: rc = read_card_mem(sc, (struct t4_mem_range *)data); break; + case CHELSIO_T4_GET_I2C: + ADAPTER_LOCK(sc); + rc = read_i2c(sc, (struct t4_i2c_data *)data); + ADAPTER_UNLOCK(sc); + break; + case CHELSIO_T4_CLEAR_STATS: { + u_int port_id = *(uint32_t *)data; + + if (port_id >= sc->params.nports) + return (EINVAL); + + t4_clr_port_stats(sc, port_id); + break; + } default: rc = EINVAL; } diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 811819fa143a..fa33d1833a68 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -120,7 +120,7 @@ static struct mbuf *get_fl_payload(struct adapter *, struct sge_fl *, uint32_t, int *); static int t4_eth_rx(struct sge_iq *, const struct rss_header *, struct mbuf *); static inline void init_iq(struct sge_iq *, struct adapter *, int, int, int, - int, char *); + int); static inline void init_fl(struct sge_fl *, int, int, char *); static inline void init_eq(struct sge_eq *, int, int, uint8_t, uint16_t, char *); @@ -319,6 +319,12 @@ t4_sge_init(struct adapter *sc) t4_write_reg(sc, A_SGE_TIMER_VALUE_4_AND_5, V_TIMERVALUE4(us_to_core_ticks(sc, intr_timer[4])) | V_TIMERVALUE5(us_to_core_ticks(sc, intr_timer[5]))); + + if (cong_drop == 0) { + t4_set_reg_field(sc, A_TP_PARA_REG3, F_TUNNELCNGDROP0 | + F_TUNNELCNGDROP1 | F_TUNNELCNGDROP2 | + F_TUNNELCNGDROP3, 0); + } } v = t4_read_reg(sc, A_SGE_CONTROL); @@ -417,22 +423,14 @@ t4_setup_adapter_queues(struct adapter *sc) * Firmware event queue */ rc = alloc_fwq(sc); - if (rc != 0) { - device_printf(sc->dev, - "failed to create firmware event queue: %d\n", rc); + if (rc != 0) return (rc); - } /* * Management queue. This is just a control queue that uses the fwq as * its associated iq. */ rc = alloc_mgmtq(sc); - if (rc != 0) { - device_printf(sc->dev, - "failed to create management queue: %d\n", rc); - return (rc); - } return (rc); } @@ -595,10 +593,8 @@ t4_setup_port_queues(struct port_info *pi) */ for_each_rxq(pi, i, rxq) { - snprintf(name, sizeof(name), "%s rxq%d-iq", - device_get_nameunit(pi->dev), i); init_iq(&rxq->iq, sc, pi->tmr_idx, pi->pktc_idx, pi->qsize_rxq, - RX_IQ_ESIZE, name); + RX_IQ_ESIZE); snprintf(name, sizeof(name), "%s rxq%d-fl", device_get_nameunit(pi->dev), i); @@ -620,10 +616,8 @@ t4_setup_port_queues(struct port_info *pi) #ifdef TCP_OFFLOAD for_each_ofld_rxq(pi, i, ofld_rxq) { - snprintf(name, sizeof(name), "%s ofld_rxq%d-iq", - device_get_nameunit(pi->dev), i); init_iq(&ofld_rxq->iq, sc, pi->tmr_idx, pi->pktc_idx, - pi->qsize_rxq, RX_IQ_ESIZE, name); + pi->qsize_rxq, RX_IQ_ESIZE); snprintf(name, sizeof(name), "%s ofld_rxq%d-fl", device_get_nameunit(pi->dev), i); @@ -1478,7 +1472,7 @@ can_resume_tx(struct sge_eq *eq) static inline void init_iq(struct sge_iq *iq, struct adapter *sc, int tmr_idx, int pktc_idx, - int qsize, int esize, char *name) + int qsize, int esize) { KASSERT(tmr_idx >= 0 && tmr_idx < SGE_NTIMERS, ("%s: bad tmr_idx %d", __func__, tmr_idx)); @@ -1495,7 +1489,6 @@ init_iq(struct sge_iq *iq, struct adapter *sc, int tmr_idx, int pktc_idx, } iq->qsize = roundup(qsize, 16); /* See FW_IQ_CMD/iqsize */ iq->esize = max(esize, 16); /* See FW_IQ_CMD/iqesize */ - strlcpy(iq->lockname, name, sizeof(iq->lockname)); } static inline void @@ -1793,12 +1786,10 @@ alloc_fwq(struct adapter *sc) { int rc, intr_idx; struct sge_iq *fwq = &sc->sge.fwq; - char name[16]; struct sysctl_oid *oid = device_get_sysctl_tree(sc->dev); struct sysctl_oid_list *children = SYSCTL_CHILDREN(oid); - snprintf(name, sizeof(name), "%s fwq", device_get_nameunit(sc->dev)); - init_iq(fwq, sc, 0, 0, FW_IQ_QSIZE, FW_IQ_ESIZE, name); + init_iq(fwq, sc, 0, 0, FW_IQ_QSIZE, FW_IQ_ESIZE); fwq->flags |= IQ_INTR; /* always */ intr_idx = sc->intr_count > 1 ? 1 : 0; rc = alloc_iq_fl(sc->port[0], fwq, NULL, intr_idx, -1); |
