Import ioctl updates for latest rev of cxgbtool

Obtained from:	Chelsio Inc.
MFC after:	3 days
This commit is contained in:
Kip Macy 2008-09-02 07:47:14 +00:00
parent dbe6d91e5c
commit 1ffd6e5809
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182679
3 changed files with 250 additions and 247 deletions

View File

@ -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 */
int32_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;
};
#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)
struct ch_eeprom {
uint32_t magic;
uint32_t offset;
uint32_t len;
uint8_t *data;
};
#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)
#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

View File

@ -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,27 +2479,16 @@ 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;
break;
}
case CHELSIO_SET_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;
/*
* XXX hardcode ourselves to 2 ports just like LEEENUX
*/
sc->port[1].first_qset = sc->port[0].nqsets;
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_GET_QSET_NUM: {
@ -2564,13 +2496,110 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
edata->val = pi->nqsets;
break;
}
#ifdef notyet
case CHELSIO_LOAD_FW:
case CHELSIO_GET_PM:
case CHELSIO_SET_PM:
return (EOPNOTSUPP);
case CHELSIO_LOAD_FW: {
uint8_t *fw_data;
uint32_t vers;
struct ch_mem_range *t = (struct ch_mem_range *)data;
/*
* 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).
*/
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;
#endif
}
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;
}
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;
}
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)
regs->len = reglen;
else if (regs->len < reglen) {
error = E2BIG;
goto done;
}
cxgb_get_regs(sc, regs, buf);
error = copyout(buf, regs->data, reglen);
done:
if (regs->len > reglen)
regs->len = reglen;
else if (regs->len < reglen)
error = E2BIG;
if (!error) {
cxgb_get_regs(sc, regs, buf);
error = copyout(buf, regs->data, reglen);
}
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);

View File

@ -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;