summaryrefslogtreecommitdiffstats
path: root/sys/dev/cxgb
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2008-09-02 07:47:14 +0000
committerkmacy <kmacy@FreeBSD.org>2008-09-02 07:47:14 +0000
commit580027241503d52b1bad46521e6e7b8066e4b23b (patch)
tree90d1d82dfd8872b6e7405ef87884696dc860e725 /sys/dev/cxgb
parentb9e54556741d38f7243ad02034c16262652f2f51 (diff)
downloadFreeBSD-src-580027241503d52b1bad46521e6e7b8066e4b23b.zip
FreeBSD-src-580027241503d52b1bad46521e6e7b8066e4b23b.tar.gz
Import ioctl updates for latest rev of cxgbtool
Obtained from: Chelsio Inc. MFC after: 3 days
Diffstat (limited to 'sys/dev/cxgb')
-rw-r--r--sys/dev/cxgb/cxgb_ioctl.h181
-rw-r--r--sys/dev/cxgb/cxgb_main.c308
-rw-r--r--sys/dev/cxgb/cxgb_sge.c2
3 files changed, 247 insertions, 244 deletions
diff --git a/sys/dev/cxgb/cxgb_ioctl.h b/sys/dev/cxgb/cxgb_ioctl.h
index 64a4ce9..7cbb746 100644
--- a/sys/dev/cxgb/cxgb_ioctl.h
+++ b/sys/dev/cxgb/cxgb_ioctl.h
@@ -37,38 +37,34 @@ $FreeBSD$
enum {
CH_SETREG = 0x40,
CH_GETREG,
- CH_SETTPI,
- CH_GETTPI,
- CH_DEVUP,
CH_GETMTUTAB,
CH_SETMTUTAB,
- CH_GETMTU,
CH_SET_PM,
CH_GET_PM,
- CH_GET_TCAM,
- CH_SET_TCAM,
- CH_GET_TCB,
CH_READ_TCAM_WORD,
CH_GET_MEM,
CH_GET_SGE_CONTEXT,
CH_GET_SGE_DESC,
CH_LOAD_FW,
- CH_GET_PROTO,
- CH_SET_PROTO,
CH_SET_TRACE_FILTER,
- CH_SET_QSET_PARAMS,
CH_GET_QSET_PARAMS,
- CH_SET_QSET_NUM,
CH_GET_QSET_NUM,
CH_SET_PKTSCHED,
CH_IFCONF_GETREGS,
- CH_GETMIIREGS,
- CH_SETMIIREGS,
- CH_SET_FILTER,
+ CH_GET_MIIREG,
+ CH_SET_MIIREG,
+ CH_GET_EEPROM,
CH_SET_HW_SCHED,
- CH_DEL_FILTER,
+ CH_LOAD_BOOT,
+ CH_CLEAR_STATS,
};
+/* statistics categories */
+enum {
+ STATS_PORT = 1 << 1,
+ STATS_QUEUE = 1 << 2,
+};
+
struct ch_reg {
uint32_t addr;
uint32_t val;
@@ -84,7 +80,6 @@ struct ch_cntxt {
enum { CNTXT_TYPE_EGRESS, CNTXT_TYPE_FL, CNTXT_TYPE_RSP, CNTXT_TYPE_CQ };
struct ch_desc {
- uint32_t cmd;
uint32_t queue_num;
uint32_t idx;
uint32_t size;
@@ -92,7 +87,6 @@ struct ch_desc {
};
struct ch_mem_range {
- uint32_t cmd;
uint32_t mem_id;
uint32_t addr;
uint32_t len;
@@ -100,21 +94,22 @@ struct ch_mem_range {
uint8_t *buf;
};
+enum { MEM_CM, MEM_PMRX, MEM_PMTX }; /* ch_mem_range.mem_id values */
+
struct ch_qset_params {
- uint32_t qset_idx;
- int32_t txq_size[3];
- int32_t rspq_size;
- int32_t fl_size[2];
- int32_t intr_lat;
- int32_t polling;
- int32_t lro;
- int32_t cong_thres;
- int32_t vector;
- int32_t qnum;
+ uint32_t qset_idx;
+ int32_t txq_size[3];
+ int32_t rspq_size;
+ int32_t fl_size[2];
+ int32_t intr_lat;
+ int32_t polling;
+ int32_t lro;
+ int32_t cong_thres;
+ int32_t vector;
+ int32_t qnum;
};
struct ch_pktsched_params {
- uint32_t cmd;
uint8_t sched;
uint8_t idx;
uint8_t min;
@@ -123,56 +118,20 @@ struct ch_pktsched_params {
};
struct ch_hw_sched {
- uint32_t cmd;
uint8_t sched;
int8_t mode;
int8_t channel;
int32_t kbps; /* rate in Kbps */
int32_t class_ipg; /* tenths of nanoseconds */
- uint32_t flow_ipg; /* usec */
-};
-
-struct ch_filter_tuple {
- uint32_t sip;
- uint32_t dip;
- uint16_t sport;
- uint16_t dport;
- uint16_t vlan:12;
- uint16_t vlan_prio:3;
-};
-
-struct ch_filter {
- uint32_t cmd;
- uint32_t filter_id;
- struct ch_filter_tuple val;
- struct ch_filter_tuple mask;
- uint16_t mac_addr_idx;
- uint8_t mac_hit:1;
- uint8_t proto:2;
-
- uint8_t want_filter_id:1; /* report filter TID instead of RSS hash */
- uint8_t pass:1; /* whether to pass or drop packets */
- uint8_t rss:1; /* use RSS or specified qset */
- uint8_t qset;
+ int32_t flow_ipg; /* usec */
};
-#ifndef TCB_SIZE
-# define TCB_SIZE 128
-#endif
-
-/* TCB size in 32-bit words */
-#define TCB_WORDS (TCB_SIZE / 4)
-
-enum { MEM_CM, MEM_PMRX, MEM_PMTX }; /* ch_mem_range.mem_id values */
-
struct ch_mtus {
- uint32_t cmd;
uint32_t nmtus;
uint16_t mtus[NMTUS];
};
struct ch_pm {
- uint32_t cmd;
uint32_t tx_pg_sz;
uint32_t tx_num_pg;
uint32_t rx_pg_sz;
@@ -180,28 +139,12 @@ struct ch_pm {
uint32_t pm_total;
};
-struct ch_tcam {
- uint32_t cmd;
- uint32_t tcam_size;
- uint32_t nservers;
- uint32_t nroutes;
- uint32_t nfilters;
-};
-
-struct ch_tcb {
- uint32_t cmd;
- uint32_t tcb_index;
- uint32_t tcb_data[TCB_WORDS];
-};
-
struct ch_tcam_word {
- uint32_t cmd;
uint32_t addr;
uint32_t buf[3];
};
struct ch_trace {
- uint32_t cmd;
uint32_t sip;
uint32_t sip_mask;
uint32_t dip;
@@ -210,57 +153,61 @@ struct ch_trace {
uint16_t sport_mask;
uint16_t dport;
uint16_t dport_mask;
- uint32_t vlan:12,
- vlan_mask:12,
- intf:4,
- intf_mask:4;
+ uint32_t vlan:12;
+ uint32_t vlan_mask:12;
+ uint32_t intf:4;
+ uint32_t intf_mask:4;
uint8_t proto;
uint8_t proto_mask;
- uint8_t invert_match:1,
- config_tx:1,
- config_rx:1,
- trace_tx:1,
- trace_rx:1;
+ uint8_t invert_match:1;
+ uint8_t config_tx:1;
+ uint8_t config_rx:1;
+ uint8_t trace_tx:1;
+ uint8_t trace_rx:1;
};
#define REGDUMP_SIZE (4 * 1024)
-struct ifconf_regs {
+struct ch_ifconf_regs {
uint32_t version;
uint32_t len; /* bytes */
uint8_t *data;
};
-struct mii_data {
+struct ch_mii_data {
uint32_t phy_id;
uint32_t reg_num;
uint32_t val_in;
uint32_t val_out;
};
-#define CHELSIO_SETREG _IOW('f', CH_SETREG, struct ch_reg)
-#define CHELSIO_GETREG _IOWR('f', CH_GETREG, struct ch_reg)
-#define CHELSIO_READ_TCAM_WORD _IOR('f', CH_READ_TCAM_WORD, struct ch_tcam)
-#define CHELSIO_GET_MEM _IOWR('f', CH_GET_MEM, struct ch_mem_range)
-#define CHELSIO_GET_SGE_CONTEXT _IOWR('f', CH_GET_SGE_CONTEXT, struct ch_cntxt)
-#define CHELSIO_GET_SGE_DESC _IOWR('f', CH_GET_SGE_DESC, struct ch_desc)
-#define CHELSIO_GET_QSET_PARAMS _IOWR('f', CH_GET_QSET_PARAMS, struct ch_qset_params)
-#define CHELSIO_SET_QSET_PARAMS _IOW('f', CH_SET_QSET_PARAMS, struct ch_qset_params)
-#define CHELSIO_GET_QSET_NUM _IOWR('f', CH_GET_QSET_NUM, struct ch_reg)
-#define CHELSIO_SET_QSET_NUM _IOW('f', CH_SET_QSET_NUM, struct ch_reg)
-#define CHELSIO_GETMTUTAB _IOR('f', CH_GET_QSET_NUM, struct ch_mtus)
-#define CHELSIO_SETMTUTAB _IOW('f', CH_SET_QSET_NUM, struct ch_mtus)
-
-
-#define CHELSIO_SET_TRACE_FILTER _IOW('f', CH_SET_TRACE_FILTER, struct ch_trace)
-#define CHELSIO_SET_PKTSCHED _IOW('f', CH_SET_PKTSCHED, struct ch_pktsched_params)
-#define CHELSIO_IFCONF_GETREGS _IOWR('f', CH_IFCONF_GETREGS, struct ifconf_regs)
-#define SIOCGMIIREG _IOWR('f', CH_GETMIIREGS, struct mii_data)
-#define SIOCSMIIREG _IOWR('f', CH_SETMIIREGS, struct mii_data)
-#define CHELSIO_SET_HW_SCHED _IOWR('f', CH_SET_HW_SCHED, struct ch_hw_sched)
-#define CHELSIO_SET_FILTER _IOW('f', CH_SET_FILTER, struct ch_filter)
-#define CHELSIO_DEL_FILTER _IOW('f', CH_DEL_FILTER, struct ch_filter)
-#define CHELSIO_DEVUP _IO('f', CH_DEVUP)
-
-#define CHELSIO_GET_TCB _IOWR('f', CH_GET_TCB, struct ch_tcb)
+struct ch_eeprom {
+ uint32_t magic;
+ uint32_t offset;
+ uint32_t len;
+ uint8_t *data;
+};
+
+#define CHELSIO_SETREG _IOW('f', CH_SETREG, struct ch_reg)
+#define CHELSIO_GETREG _IOWR('f', CH_GETREG, struct ch_reg)
+#define CHELSIO_GETMTUTAB _IOR('f', CH_GETMTUTAB, struct ch_mtus)
+#define CHELSIO_SETMTUTAB _IOW('f', CH_SETMTUTAB, struct ch_mtus)
+#define CHELSIO_SET_PM _IOW('f', CH_SET_PM, struct ch_pm)
+#define CHELSIO_GET_PM _IOR('f', CH_GET_PM, struct ch_pm)
+#define CHELSIO_READ_TCAM_WORD _IOWR('f', CH_READ_TCAM_WORD, struct ch_tcam_word)
+#define CHELSIO_GET_MEM _IOWR('f', CH_GET_MEM, struct ch_mem_range)
+#define CHELSIO_GET_SGE_CONTEXT _IOWR('f', CH_GET_SGE_CONTEXT, struct ch_cntxt)
+#define CHELSIO_GET_SGE_DESC _IOWR('f', CH_GET_SGE_DESC, struct ch_desc)
+#define CHELSIO_LOAD_FW _IOWR('f', CH_LOAD_FW, struct ch_mem_range)
+#define CHELSIO_SET_TRACE_FILTER _IOW('f', CH_SET_TRACE_FILTER, struct ch_trace)
+#define CHELSIO_GET_QSET_PARAMS _IOWR('f', CH_GET_QSET_PARAMS, struct ch_qset_params)
+#define CHELSIO_GET_QSET_NUM _IOR('f', CH_GET_QSET_NUM, struct ch_reg)
+#define CHELSIO_SET_PKTSCHED _IOW('f', CH_SET_PKTSCHED, struct ch_pktsched_params)
+#define CHELSIO_SET_HW_SCHED _IOW('f', CH_SET_HW_SCHED, struct ch_hw_sched)
+#define CHELSIO_LOAD_BOOT _IOW('f', CH_LOAD_BOOT, struct ch_mem_range)
+#define CHELSIO_CLEAR_STATS _IO('f', CH_CLEAR_STATS)
+#define CHELSIO_IFCONF_GETREGS _IOWR('f', CH_IFCONF_GETREGS, struct ch_ifconf_regs)
+#define CHELSIO_GET_MIIREG _IOWR('f', CH_GET_MIIREG, struct ch_mii_data)
+#define CHELSIO_SET_MIIREG _IOW('f', CH_SET_MIIREG, struct ch_mii_data)
+#define CHELSIO_GET_EEPROM _IOWR('f', CH_GET_EEPROM, struct ch_eeprom)
#endif
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index e08eb02..aaa497d 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -116,7 +116,7 @@ static int cxgb_controller_detach(device_t);
static void cxgb_free(struct adapter *);
static __inline void reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
unsigned int end);
-static void cxgb_get_regs(adapter_t *sc, struct ifconf_regs *regs, uint8_t *buf);
+static void cxgb_get_regs(adapter_t *sc, struct ch_ifconf_regs *regs, uint8_t *buf);
static int cxgb_get_regs_len(void);
static int offload_open(struct port_info *pi);
static void touch_bars(device_t dev);
@@ -267,6 +267,8 @@ struct filter_info {
enum { FILTER_NO_VLAN_PRI = 7 };
+#define EEPROM_MAGIC 0x38E2F10C
+
#define PORT_MASK ((1 << MAX_NPORTS) - 1)
/* Table for probing the cards. The desc field isn't actually used */
@@ -2361,10 +2363,10 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
#endif
switch (cmd) {
- case SIOCGMIIREG: {
+ case CHELSIO_GET_MIIREG: {
uint32_t val;
struct cphy *phy = &pi->phy;
- struct mii_data *mid = (struct mii_data *)data;
+ struct ch_mii_data *mid = (struct ch_mii_data *)data;
if (!phy->mdio_read)
return (EOPNOTSUPP);
@@ -2384,9 +2386,9 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
mid->val_out = val;
break;
}
- case SIOCSMIIREG: {
+ case CHELSIO_SET_MIIREG: {
struct cphy *phy = &pi->phy;
- struct mii_data *mid = (struct mii_data *)data;
+ struct ch_mii_data *mid = (struct ch_mii_data *)data;
if (!phy->mdio_write)
return (EOPNOTSUPP);
@@ -2424,19 +2426,19 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
mtx_lock_spin(&sc->sge.reg_lock);
switch (ecntxt->cntxt_type) {
case CNTXT_TYPE_EGRESS:
- error = t3_sge_read_ecntxt(sc, ecntxt->cntxt_id,
+ error = -t3_sge_read_ecntxt(sc, ecntxt->cntxt_id,
ecntxt->data);
break;
case CNTXT_TYPE_FL:
- error = t3_sge_read_fl(sc, ecntxt->cntxt_id,
+ error = -t3_sge_read_fl(sc, ecntxt->cntxt_id,
ecntxt->data);
break;
case CNTXT_TYPE_RSP:
- error = t3_sge_read_rspq(sc, ecntxt->cntxt_id,
+ error = -t3_sge_read_rspq(sc, ecntxt->cntxt_id,
ecntxt->data);
break;
case CNTXT_TYPE_CQ:
- error = t3_sge_read_cq(sc, ecntxt->cntxt_id,
+ error = -t3_sge_read_cq(sc, ecntxt->cntxt_id,
ecntxt->data);
break;
default:
@@ -2458,77 +2460,18 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
edesc->size = ret;
break;
}
- case CHELSIO_SET_QSET_PARAMS: {
- struct qset_params *q;
- struct ch_qset_params *t = (struct ch_qset_params *)data;
- int i;
-
- if (t->qset_idx >= SGE_QSETS)
- return (EINVAL);
- if (!in_range(t->intr_lat, 0, M_NEWTIMER) ||
- !in_range(t->cong_thres, 0, 255) ||
- !in_range(t->txq_size[0], MIN_TXQ_ENTRIES,
- MAX_TXQ_ENTRIES) ||
- !in_range(t->txq_size[1], MIN_TXQ_ENTRIES,
- MAX_TXQ_ENTRIES) ||
- !in_range(t->txq_size[2], MIN_CTRL_TXQ_ENTRIES,
- MAX_CTRL_TXQ_ENTRIES) ||
- !in_range(t->fl_size[0], MIN_FL_ENTRIES, MAX_RX_BUFFERS) ||
- !in_range(t->fl_size[1], MIN_FL_ENTRIES,
- MAX_RX_JUMBO_BUFFERS) ||
- !in_range(t->rspq_size, MIN_RSPQ_ENTRIES, MAX_RSPQ_ENTRIES))
- return (EINVAL);
-
- if ((sc->flags & FULL_INIT_DONE) && t->lro > 0)
- for_each_port(sc, i) {
- pi = adap2pinfo(sc, i);
- if (t->qset_idx >= pi->first_qset &&
- t->qset_idx < pi->first_qset + pi->nqsets
-#if 0
- && !pi->rx_csum_offload
-#endif
- )
- return -EINVAL;
- }
- if ((sc->flags & FULL_INIT_DONE) &&
- (t->rspq_size >= 0 || t->fl_size[0] >= 0 ||
- t->fl_size[1] >= 0 || t->txq_size[0] >= 0 ||
- t->txq_size[1] >= 0 || t->txq_size[2] >= 0 ||
- t->polling >= 0 || t->cong_thres >= 0))
- return (EBUSY);
-
- q = &sc->params.sge.qset[t->qset_idx];
-
- if (t->rspq_size >= 0)
- q->rspq_size = t->rspq_size;
- if (t->fl_size[0] >= 0)
- q->fl_size = t->fl_size[0];
- if (t->fl_size[1] >= 0)
- q->jumbo_size = t->fl_size[1];
- if (t->txq_size[0] >= 0)
- q->txq_size[0] = t->txq_size[0];
- if (t->txq_size[1] >= 0)
- q->txq_size[1] = t->txq_size[1];
- if (t->txq_size[2] >= 0)
- q->txq_size[2] = t->txq_size[2];
- if (t->cong_thres >= 0)
- q->cong_thres = t->cong_thres;
- if (t->intr_lat >= 0) {
- struct sge_qset *qs = &sc->sge.qs[t->qset_idx];
-
- q->coalesce_usecs = t->intr_lat;
- t3_update_qset_coalesce(qs, q);
- }
- break;
- }
case CHELSIO_GET_QSET_PARAMS: {
struct qset_params *q;
struct ch_qset_params *t = (struct ch_qset_params *)data;
+ int q1 = pi->first_qset;
+ int nqsets = pi->nqsets;
+ int i;
- if (t->qset_idx >= SGE_QSETS)
- return (EINVAL);
+ if (t->qset_idx >= nqsets)
+ return EINVAL;
- q = &(sc)->params.sge.qset[t->qset_idx];
+ i = q1 + t->qset_idx;
+ q = &sc->params.sge.qset[i];
t->rspq_size = q->rspq_size;
t->txq_size[0] = q->txq_size[0];
t->txq_size[1] = q->txq_size[1];
@@ -2536,41 +2479,127 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
t->fl_size[0] = q->fl_size;
t->fl_size[1] = q->jumbo_size;
t->polling = q->polling;
+ t->lro = q->lro;
t->intr_lat = q->coalesce_usecs;
t->cong_thres = q->cong_thres;
+ t->qnum = i;
+
+ if (sc->flags & USING_MSIX)
+ t->vector = rman_get_start(sc->msix_irq_res[i]);
+ else
+ t->vector = rman_get_start(sc->irq_res);
+
break;
}
- case CHELSIO_SET_QSET_NUM: {
+ case CHELSIO_GET_QSET_NUM: {
struct ch_reg *edata = (struct ch_reg *)data;
- unsigned int port_idx = pi->port_id;
-
- if (sc->flags & FULL_INIT_DONE)
- return (EBUSY);
- if (edata->val < 1 ||
- (edata->val > 1 && !(sc->flags & USING_MSIX)))
- return (EINVAL);
- if (edata->val + sc->port[!port_idx].nqsets > SGE_QSETS)
- return (EINVAL);
- sc->port[port_idx].nqsets = edata->val;
- sc->port[0].first_qset = 0;
+ edata->val = pi->nqsets;
+ break;
+ }
+ case CHELSIO_LOAD_FW: {
+ uint8_t *fw_data;
+ uint32_t vers;
+ struct ch_mem_range *t = (struct ch_mem_range *)data;
+
/*
- * XXX hardcode ourselves to 2 ports just like LEEENUX
+ * You're allowed to load a firmware only before FULL_INIT_DONE
+ *
+ * FW_UPTODATE is also set so the rest of the initialization
+ * will not overwrite what was loaded here. This gives you the
+ * flexibility to load any firmware (and maybe shoot yourself in
+ * the foot).
*/
- sc->port[1].first_qset = sc->port[0].nqsets;
+
+ ADAPTER_LOCK(sc);
+ if (sc->open_device_map || sc->flags & FULL_INIT_DONE) {
+ ADAPTER_UNLOCK(sc);
+ return (EBUSY);
+ }
+
+ fw_data = malloc(t->len, M_DEVBUF, M_NOWAIT);
+ if (!fw_data)
+ error = ENOMEM;
+ else
+ error = copyin(t->buf, fw_data, t->len);
+
+ if (!error)
+ error = -t3_load_fw(sc, fw_data, t->len);
+
+ if (t3_get_fw_version(sc, &vers) == 0) {
+ snprintf(&sc->fw_version[0], sizeof(sc->fw_version),
+ "%d.%d.%d", G_FW_VERSION_MAJOR(vers),
+ G_FW_VERSION_MINOR(vers), G_FW_VERSION_MICRO(vers));
+ }
+
+ if (!error)
+ sc->flags |= FW_UPTODATE;
+
+ free(fw_data, M_DEVBUF);
+ ADAPTER_UNLOCK(sc);
break;
}
- case CHELSIO_GET_QSET_NUM: {
- struct ch_reg *edata = (struct ch_reg *)data;
- edata->val = pi->nqsets;
+ case CHELSIO_LOAD_BOOT: {
+ uint8_t *boot_data;
+ struct ch_mem_range *t = (struct ch_mem_range *)data;
+
+ boot_data = malloc(t->len, M_DEVBUF, M_NOWAIT);
+ if (!boot_data)
+ return ENOMEM;
+
+ error = copyin(t->buf, boot_data, t->len);
+ if (!error)
+ error = -t3_load_boot(sc, boot_data, t->len);
+
+ free(boot_data, M_DEVBUF);
break;
}
-#ifdef notyet
- case CHELSIO_LOAD_FW:
- case CHELSIO_GET_PM:
- case CHELSIO_SET_PM:
- return (EOPNOTSUPP);
+ case CHELSIO_GET_PM: {
+ struct ch_pm *m = (struct ch_pm *)data;
+ struct tp_params *p = &sc->params.tp;
+
+ if (!is_offload(sc))
+ return (EOPNOTSUPP);
+
+ m->tx_pg_sz = p->tx_pg_size;
+ m->tx_num_pg = p->tx_num_pgs;
+ m->rx_pg_sz = p->rx_pg_size;
+ m->rx_num_pg = p->rx_num_pgs;
+ m->pm_total = p->pmtx_size + p->chan_rx_size * p->nchan;
+
break;
-#endif
+ }
+ case CHELSIO_SET_PM: {
+ struct ch_pm *m = (struct ch_pm *)data;
+ struct tp_params *p = &sc->params.tp;
+
+ if (!is_offload(sc))
+ return (EOPNOTSUPP);
+ if (sc->flags & FULL_INIT_DONE)
+ return (EBUSY);
+
+ if (!m->rx_pg_sz || (m->rx_pg_sz & (m->rx_pg_sz - 1)) ||
+ !m->tx_pg_sz || (m->tx_pg_sz & (m->tx_pg_sz - 1)))
+ return (EINVAL); /* not power of 2 */
+ if (!(m->rx_pg_sz & 0x14000))
+ return (EINVAL); /* not 16KB or 64KB */
+ if (!(m->tx_pg_sz & 0x1554000))
+ return (EINVAL);
+ if (m->tx_num_pg == -1)
+ m->tx_num_pg = p->tx_num_pgs;
+ if (m->rx_num_pg == -1)
+ m->rx_num_pg = p->rx_num_pgs;
+ if (m->tx_num_pg % 24 || m->rx_num_pg % 24)
+ return (EINVAL);
+ if (m->rx_num_pg * m->rx_pg_sz > p->chan_rx_size ||
+ m->tx_num_pg * m->tx_pg_sz > p->chan_tx_size)
+ return (EINVAL);
+
+ p->rx_pg_size = m->rx_pg_sz;
+ p->tx_pg_size = m->tx_pg_sz;
+ p->rx_num_pgs = m->rx_num_pg;
+ p->tx_num_pgs = m->tx_num_pg;
+ break;
+ }
case CHELSIO_SETMTUTAB: {
struct ch_mtus *m = (struct ch_mtus *)data;
int i;
@@ -2591,8 +2620,7 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
if (m->mtus[i] < m->mtus[i - 1])
return (EINVAL);
- memcpy(sc->params.mtus, m->mtus,
- sizeof(sc->params.mtus));
+ memcpy(sc->params.mtus, m->mtus, sizeof(sc->params.mtus));
break;
}
case CHELSIO_GETMTUTAB: {
@@ -2605,22 +2633,23 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
m->nmtus = NMTUS;
break;
}
- case CHELSIO_DEVUP:
- if (!is_offload(sc))
- return (EOPNOTSUPP);
- return offload_open(pi);
- break;
case CHELSIO_GET_MEM: {
struct ch_mem_range *t = (struct ch_mem_range *)data;
struct mc7 *mem;
uint8_t *useraddr;
u64 buf[32];
-
+
+ /*
+ * Use these to avoid modifying len/addr in the the return
+ * struct
+ */
+ uint32_t len = t->len, addr = t->addr;
+
if (!is_offload(sc))
return (EOPNOTSUPP);
if (!(sc->flags & FULL_INIT_DONE))
return (EIO); /* need the memory controllers */
- if ((t->addr & 0x7) || (t->len & 0x7))
+ if ((addr & 0x7) || (len & 0x7))
return (EINVAL);
if (t->mem_id == MEM_CM)
mem = &sc->cm;
@@ -2643,17 +2672,17 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
* want to use huge intermediate buffers.
*/
useraddr = (uint8_t *)t->buf;
- while (t->len) {
- unsigned int chunk = min(t->len, sizeof(buf));
+ while (len) {
+ unsigned int chunk = min(len, sizeof(buf));
- error = t3_mc7_bd_read(mem, t->addr / 8, chunk / 8, buf);
+ error = t3_mc7_bd_read(mem, addr / 8, chunk / 8, buf);
if (error)
return (-error);
if (copyout(buf, useraddr, chunk))
return (EFAULT);
useraddr += chunk;
- t->addr += chunk;
- t->len -= chunk;
+ addr += chunk;
+ len -= chunk;
}
break;
}
@@ -2689,21 +2718,21 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
break;
}
case CHELSIO_IFCONF_GETREGS: {
- struct ifconf_regs *regs = (struct ifconf_regs *)data;
+ struct ch_ifconf_regs *regs = (struct ch_ifconf_regs *)data;
int reglen = cxgb_get_regs_len();
- uint8_t *buf = malloc(REGDUMP_SIZE, M_DEVBUF, M_NOWAIT);
+ uint8_t *buf = malloc(reglen, M_DEVBUF, M_NOWAIT);
if (buf == NULL) {
return (ENOMEM);
- } if (regs->len > reglen)
+ }
+ if (regs->len > reglen)
regs->len = reglen;
- else if (regs->len < reglen) {
+ else if (regs->len < reglen)
error = E2BIG;
- goto done;
+
+ if (!error) {
+ cxgb_get_regs(sc, regs, buf);
+ error = copyout(buf, regs->data, reglen);
}
- cxgb_get_regs(sc, regs, buf);
- error = copyout(buf, regs->data, reglen);
-
- done:
free(buf, M_DEVBUF);
break;
@@ -2743,7 +2772,35 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
t3_set_reg_field(sc, A_TP_TX_MOD_QUEUE_REQ_MAP,
1 << t->sched, t->channel << t->sched);
break;
- }
+ }
+ case CHELSIO_GET_EEPROM: {
+ int i;
+ struct ch_eeprom *e = (struct ch_eeprom *)data;
+ uint8_t *buf = malloc(EEPROMSIZE, M_DEVBUF, M_NOWAIT);
+
+ if (buf == NULL) {
+ return (ENOMEM);
+ }
+ e->magic = EEPROM_MAGIC;
+ for (i = e->offset & ~3; !error && i < e->offset + e->len; i += 4)
+ error = -t3_seeprom_read(sc, i, (uint32_t *)&buf[i]);
+
+ if (!error)
+ error = copyout(buf + e->offset, e->data, e->len);
+
+ free(buf, M_DEVBUF);
+ break;
+ }
+ case CHELSIO_CLEAR_STATS: {
+ if (!(sc->flags & FULL_INIT_DONE))
+ return EAGAIN;
+
+ PORT_LOCK(pi);
+ t3_mac_update_stats(&pi->mac);
+ memset(&pi->mac.stats, 0, sizeof(pi->mac.stats));
+ PORT_UNLOCK(pi);
+ break;
+ }
default:
return (EOPNOTSUPP);
break;
@@ -2756,7 +2813,7 @@ static __inline void
reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
unsigned int end)
{
- uint32_t *p = (uint32_t *)buf + start;
+ uint32_t *p = (uint32_t *)(buf + start);
for ( ; start <= end; start += sizeof(uint32_t))
*p++ = t3_read_reg(ap, start);
@@ -2768,10 +2825,9 @@ cxgb_get_regs_len(void)
{
return T3_REGMAP_SIZE;
}
-#undef T3_REGMAP_SIZE
static void
-cxgb_get_regs(adapter_t *sc, struct ifconf_regs *regs, uint8_t *buf)
+cxgb_get_regs(adapter_t *sc, struct ch_ifconf_regs *regs, uint8_t *buf)
{
/*
@@ -2787,7 +2843,7 @@ cxgb_get_regs(adapter_t *sc, struct ifconf_regs *regs, uint8_t *buf)
* Also reading multi-register stats would need to synchronize with the
* periodic mac stats accumulation. Hard to justify the complexity.
*/
- memset(buf, 0, REGDUMP_SIZE);
+ memset(buf, 0, cxgb_get_regs_len());
reg_block_dump(sc, buf, 0, A_SG_RSPQ_CREDIT_RETURN);
reg_block_dump(sc, buf, A_SG_HI_DRB_HI_THRSH, A_ULPRX_PBL_ULIMIT);
reg_block_dump(sc, buf, A_ULPTX_CONFIG, A_MPS_INT_CAUSE);
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 46cb31e..3ff3977 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -401,7 +401,7 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
q->coalesce_usecs = 5;
#endif
}
- q->polling = adap->params.rev > 0;
+ q->polling = 0;
q->rspq_size = RSPQ_Q_SIZE;
q->fl_size = fl_q_size;
q->jumbo_size = jumbo_q_size;
OpenPOWER on IntegriCloud