summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-10-29 18:22:12 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-10-29 18:22:12 +0000
commitbdd6cb3b208227cc5bb98d24c6b2a44666658b2e (patch)
tree78dc6bac169bbb0b50b6f88c9669ebfb99a44c02
parent4816cdd619ff485d8a4b102aad4f40afa2f0b1ea (diff)
rename oce_fw to oce_cmd and shorten MBX_SUBSYSTEM_* defines to SUBSYS_
-rw-r--r--sys/dev/pci/oce.c72
-rw-r--r--sys/dev/pci/ocereg.h121
2 files changed, 65 insertions, 128 deletions
diff --git a/sys/dev/pci/oce.c b/sys/dev/pci/oce.c
index 8297a223905..8c1945157ae 100644
--- a/sys/dev/pci/oce.c
+++ b/sys/dev/pci/oce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: oce.c,v 1.21 2012/10/29 18:17:39 mikeb Exp $ */
+/* $OpenBSD: oce.c,v 1.22 2012/10/29 18:22:11 mikeb Exp $ */
/*
* Copyright (c) 2012 Mike Belopuhov
@@ -98,7 +98,7 @@
int oce_mbox_dispatch(struct oce_softc *sc);
-int oce_fw(struct oce_softc *sc, int subsys, int opcode, int version,
+int oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
void *payload, int length);
int oce_config_vlan(struct oce_softc *sc, uint32_t if_id,
@@ -145,9 +145,9 @@ oce_init_fw(struct oce_softc *sc)
/* reset FW */
if (sc->flags & OCE_FLAGS_RESET_RQD) {
bzero(&fwcmd, sizeof(fwcmd));
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
- OPCODE_COMMON_FUNCTION_RESET, OCE_MBX_VER_V0,
- &fwcmd, sizeof(fwcmd));
+ err = oce_cmd(sc, SUBSYS_COMMON,
+ OPCODE_COMMON_FUNCTION_RESET,
+ OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
}
return (err);
}
@@ -239,7 +239,7 @@ oce_mbox_init(struct oce_softc *sc)
}
int
-oce_fw(struct oce_softc *sc, int subsys, int opcode, int version,
+oce_cmd(struct oce_softc *sc, int subsys, int opcode, int version,
void *payload, int length)
{
struct oce_bmbx *bmbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
@@ -320,7 +320,7 @@ oce_first_mcc(struct oce_softc *sc)
fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
hdr = &fwcmd->hdr;
- hdr->u0.req.subsystem = MBX_SUBSYSTEM_COMMON;
+ hdr->u0.req.subsystem = SUBSYS_COMMON;
hdr->u0.req.opcode = OPCODE_COMMON_GET_FW_VERSION;
hdr->u0.req.version = OCE_MBX_VER_V0;
hdr->u0.req.timeout = MBX_TIMEOUT_SEC;
@@ -378,7 +378,7 @@ oce_create_iface(struct oce_softc *sc, uint8_t *macaddr)
} else
fwcmd.params.req.mac_invalid = 1;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_IFACE,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_IFACE,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -433,7 +433,7 @@ oce_config_vlan(struct oce_softc *sc, uint32_t if_id,
bcopy(vtag_arr, fwcmd.params.req.tags.normal_vlans,
vtag_cnt * sizeof(struct normal_vlan));
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CONFIG_IFACE_VLAN,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CONFIG_IFACE_VLAN,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return (err);
}
@@ -457,7 +457,7 @@ oce_set_flow_control(struct oce_softc *sc, uint32_t flow_control)
if (flow_control & OCE_FC_RX)
fwcmd.rx_flow_control = 1;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_SET_FLOW_CONTROL,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_FLOW_CONTROL,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return (err);
}
@@ -508,7 +508,7 @@ oce_config_rss(struct oce_softc *sc, uint32_t if_id, int enable)
else
return (ENXIO);
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_CONFIG_RSS,
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CONFIG_RSS,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return (err);
}
@@ -533,9 +533,8 @@ oce_update_mcast(struct oce_softc *sc,
fwcmd.params.req.num_mac = htole16(naddr);
fwcmd.params.req.if_id = sc->if_id;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
- OPCODE_COMMON_SET_IFACE_MULTICAST, OCE_MBX_VER_V0,
- &fwcmd, sizeof(fwcmd));
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_MULTICAST,
+ OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return (err);
}
@@ -564,7 +563,7 @@ oce_set_promisc(struct oce_softc *sc, int enable)
if (enable)
req->iface_flags = req->iface_flags_mask;
- rc = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_SET_IFACE_RX_FILTER,
+ rc = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_SET_IFACE_RX_FILTER,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return rc;
@@ -585,7 +584,7 @@ oce_get_link_status(struct oce_softc *sc)
bzero(&fwcmd, sizeof(fwcmd));
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_QUERY_LINK_CONFIG,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_LINK_CONFIG,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -622,7 +621,7 @@ oce_macaddr_get(struct oce_softc *sc, uint8_t *macaddr)
fwcmd.params.req.type = MAC_ADDRESS_TYPE_NETWORK;
fwcmd.params.req.permanent = 1;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_QUERY_IFACE_MAC,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err == 0)
bcopy(&fwcmd.params.rsp.mac.mac_addr[0], macaddr, ETH_ADDR_LEN);
@@ -641,7 +640,7 @@ oce_macaddr_add(struct oce_softc *sc, uint8_t *enaddr, uint32_t if_id,
fwcmd.params.req.if_id = htole16(if_id);
bcopy(enaddr, fwcmd.params.req.mac_address, ETH_ADDR_LEN);
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_ADD_IFACE_MAC,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_ADD_IFACE_MAC,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err == 0)
*pmac_id = letoh32(fwcmd.params.rsp.pmac_id);
@@ -659,7 +658,7 @@ oce_macaddr_del(struct oce_softc *sc, uint32_t if_id, uint32_t pmac_id)
fwcmd.params.req.if_id = htole16(if_id);
fwcmd.params.req.pmac_id = htole32(pmac_id);
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_DEL_IFACE_MAC,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_DEL_IFACE_MAC,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
return (err);
}
@@ -676,7 +675,7 @@ oce_check_native_mode(struct oce_softc *sc)
CAP_BE3_NATIVE_ERX_API;
fwcmd.params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON,
+ err = oce_cmd(sc, SUBSYS_COMMON,
OPCODE_COMMON_SET_FUNCTIONAL_CAPS, OCE_MBX_VER_V0, &fwcmd,
sizeof(fwcmd));
if (err)
@@ -714,7 +713,7 @@ oce_new_rq(struct oce_softc *sc, struct oce_rq *rq)
fwcmd.params.req.max_frame_size = htole16(rq->cfg.mtu);
fwcmd.params.req.is_rss_queue = htole32(rq->cfg.is_rss_queue);
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_CREATE_RQ,
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_RQ,
IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &fwcmd,
sizeof(fwcmd));
if (err)
@@ -749,7 +748,7 @@ oce_new_wq(struct oce_softc *sc, struct oce_wq *wq)
fwcmd.params.req.cq_id = htole16(wq->cq->id);
fwcmd.params.req.ulp_num = 1;
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_CREATE_WQ,
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_CREATE_WQ,
IS_XE201(sc) ? OCE_MBX_VER_V1 : OCE_MBX_VER_V0, &fwcmd,
sizeof(fwcmd));
if (err)
@@ -784,7 +783,7 @@ oce_new_mq(struct oce_softc *sc, struct oce_mq *mq)
/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
ctx->v0.async_evt_bitmap = 0xffffffff;
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_MQ_EXT,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_MQ_EXT,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -816,7 +815,7 @@ oce_new_eq(struct oce_softc *sc, struct oce_eq *eq)
fwcmd.params.req.ctx.armed = 0;
fwcmd.params.req.ctx.delay_mult = htole32(eq->cfg.cur_eqd);
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_EQ,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_EQ,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -871,7 +870,7 @@ oce_new_cq(struct oce_softc *sc, struct oce_cq *cq)
ctx->v0.eq_id = cq->eq->id;
}
- err = oce_fw(sc, MBX_SUBSYSTEM_COMMON, OPCODE_COMMON_CREATE_CQ,
+ err = oce_cmd(sc, SUBSYS_COMMON, OPCODE_COMMON_CREATE_CQ,
IS_XE201(sc) ? OCE_MBX_VER_V2 : OCE_MBX_VER_V0, &fwcmd,
sizeof(fwcmd));
if (err)
@@ -891,23 +890,23 @@ oce_destroy_queue(struct oce_softc *sc, enum qtype qtype, uint32_t qid)
switch (qtype) {
case QTYPE_CQ:
opcode = OPCODE_COMMON_DESTROY_CQ;
- subsys = MBX_SUBSYSTEM_COMMON;
+ subsys = SUBSYS_COMMON;
break;
case QTYPE_EQ:
opcode = OPCODE_COMMON_DESTROY_EQ;
- subsys = MBX_SUBSYSTEM_COMMON;
+ subsys = SUBSYS_COMMON;
break;
case QTYPE_MQ:
opcode = OPCODE_COMMON_DESTROY_MQ;
- subsys = MBX_SUBSYSTEM_COMMON;
+ subsys = SUBSYS_COMMON;
break;
case QTYPE_RQ:
opcode = OPCODE_NIC_DELETE_RQ;
- subsys = MBX_SUBSYSTEM_NIC;
+ subsys = SUBSYS_NIC;
break;
case QTYPE_WQ:
opcode = OPCODE_NIC_DELETE_WQ;
- subsys = MBX_SUBSYSTEM_NIC;
+ subsys = SUBSYS_NIC;
break;
default:
return (EINVAL);
@@ -917,7 +916,8 @@ oce_destroy_queue(struct oce_softc *sc, enum qtype qtype, uint32_t qid)
fwcmd.params.req.id = htole16(qid);
- err = oce_fw(sc, subsys, opcode, OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
+ err = oce_cmd(sc, subsys, opcode, OCE_MBX_VER_V0, &fwcmd,
+ sizeof(fwcmd));
return (err);
}
@@ -932,8 +932,8 @@ oce_stats_be2(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
bzero(&fwcmd, sizeof(fwcmd));
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_GET_STATS,
- OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V0,
+ &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -971,8 +971,8 @@ oce_stats_be3(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
bzero(&fwcmd, sizeof(fwcmd));
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_GET_STATS,
- OCE_MBX_VER_V1, &fwcmd, sizeof(fwcmd));
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_STATS, OCE_MBX_VER_V1,
+ &fwcmd, sizeof(fwcmd));
if (err)
return (err);
@@ -1007,7 +1007,7 @@ oce_stats_xe(struct oce_softc *sc, uint64_t *rxe, uint64_t *txe)
fwcmd.params.req.reset_stats = 0;
fwcmd.params.req.port_number = sc->if_id;
- err = oce_fw(sc, MBX_SUBSYSTEM_NIC, OPCODE_NIC_GET_PPORT_STATS,
+ err = oce_cmd(sc, SUBSYS_NIC, OPCODE_NIC_GET_PPORT_STATS,
OCE_MBX_VER_V0, &fwcmd, sizeof(fwcmd));
if (err)
return (err);
diff --git a/sys/dev/pci/ocereg.h b/sys/dev/pci/ocereg.h
index 78dd1a9e6bb..833cf2bfa99 100644
--- a/sys/dev/pci/ocereg.h
+++ b/sys/dev/pci/ocereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ocereg.h,v 1.12 2012/10/27 00:03:55 mikeb Exp $ */
+/* $OpenBSD: ocereg.h,v 1.13 2012/10/29 18:22:11 mikeb Exp $ */
/*-
* Copyright (C) 2012 Emulex
@@ -438,32 +438,31 @@ struct oce_bmbx {
struct oce_mq_cqe cqe;
} __packed;
-/* ---[ MBXs start here ]---------------------------------------------- */
/* MBXs sub system codes */
-enum MBX_SUBSYSTEM_CODES {
- MBX_SUBSYSTEM_RSVD = 0,
- MBX_SUBSYSTEM_COMMON = 1,
- MBX_SUBSYSTEM_COMMON_ISCSI = 2,
- MBX_SUBSYSTEM_NIC = 3,
- MBX_SUBSYSTEM_TOE = 4,
- MBX_SUBSYSTEM_PXE_UNDI = 5,
- MBX_SUBSYSTEM_ISCSI_INI = 6,
- MBX_SUBSYSTEM_ISCSI_TGT = 7,
- MBX_SUBSYSTEM_MILI_PTL = 8,
- MBX_SUBSYSTEM_MILI_TMD = 9,
- MBX_SUBSYSTEM_RDMA = 10,
- MBX_SUBSYSTEM_LOWLEVEL = 11,
- MBX_SUBSYSTEM_LRO = 13,
- IOCBMBX_SUBSYSTEM_DCBX = 15,
- IOCBMBX_SUBSYSTEM_DIAG = 16,
- IOCBMBX_SUBSYSTEM_VENDOR = 17
+enum SUBSYS_CODES {
+ SUBSYS_RSVD = 0,
+ SUBSYS_COMMON = 1,
+ SUBSYS_COMMON_ISCSI = 2,
+ SUBSYS_NIC = 3,
+ SUBSYS_TOE = 4,
+ SUBSYS_PXE_UNDI = 5,
+ SUBSYS_ISCSI_INI = 6,
+ SUBSYS_ISCSI_TGT = 7,
+ SUBSYS_MILI_PTL = 8,
+ SUBSYS_MILI_TMD = 9,
+ SUBSYS_RDMA = 10,
+ SUBSYS_LOWLEVEL = 11,
+ SUBSYS_LRO = 13,
+ SUBSYS_DCBX = 15,
+ SUBSYS_DIAG = 16,
+ SUBSYS_VENDOR = 17
};
/* common ioctl opcodes */
-enum COMMON_SUBSYSTEM_OPCODES {
+enum COMMON_SUBSYS_OPCODES {
/* These opcodes are common to both networking and storage PCI functions
* They are used to reserve resources and configure CNA. These opcodes
- * all use the MBX_SUBSYSTEM_COMMON subsystem code.
+ * all use the SUBSYS_COMMON subsystem code.
*/
OPCODE_COMMON_QUERY_IFACE_MAC = 1,
OPCODE_COMMON_SET_IFACE_MAC = 2,
@@ -1165,22 +1164,6 @@ struct mbx_common_get_set_flow_control {
#endif
} __packed;
-enum e_flash_opcode {
- MGMT_FLASHROM_OPCODE_FLASH = 1,
- MGMT_FLASHROM_OPCODE_SAVE = 2
-};
-
-/* [06] OPCODE_READ_COMMON_FLASHROM */
-/* [07] OPCODE_WRITE_COMMON_FLASHROM */
-struct mbx_common_read_write_flashrom {
- struct mbx_hdr hdr;
- uint32_t flash_op_code;
- uint32_t flash_op_type;
- uint32_t data_buffer_size;
- uint32_t data_offset;
- uint8_t data_buffer[4]; /* + IMAGE_TRANSFER_SIZE */
-} __packed;
-
struct oce_phy_info {
uint16_t phy_type;
uint16_t interface_type;
@@ -1529,70 +1512,24 @@ struct mbx_lowlevel_set_loopback_mode {
} params;
} __packed;
-struct flash_file_hdr {
- uint8_t sign[52];
- uint8_t ufi_version[4];
- uint32_t file_len;
- uint32_t cksum;
- uint32_t antidote;
- uint32_t num_imgs;
- uint8_t build[24];
- uint8_t rsvd[32];
-} __packed;
-
-struct image_hdr {
- uint32_t imageid;
- uint32_t imageoffset;
- uint32_t imagelength;
- uint32_t image_checksum;
- uint8_t image_version[32];
-} __packed;
-
-struct flash_section_hdr {
- uint32_t format_rev;
- uint32_t cksum;
- uint32_t antidote;
- uint32_t num_images;
- uint8_t id_string[128];
- uint32_t rsvd[4];
-} __packed;
-
-struct flash_section_entry {
- uint32_t type;
- uint32_t offset;
- uint32_t pad_size;
- uint32_t image_size;
- uint32_t cksum;
- uint32_t entry_point;
- uint32_t rsvd0;
- uint32_t rsvd1;
- uint8_t ver_data[32];
-} __packed;
-
-struct flash_sec_info {
- uint8_t cookie[32];
- struct flash_section_hdr fsec_hdr;
- struct flash_section_entry fsec_entry[32];
-} __packed;
-
-enum LOWLEVEL_SUBSYSTEM_OPCODES {
+enum LOWLEVEL_SUBSYS_OPCODES {
/* Opcodes used for lowlevel functions common to many subystems.
* Some of these opcodes are used for diagnostic functions only.
- * These opcodes use the MBX_SUBSYSTEM_LOWLEVEL subsystem code.
+ * These opcodes use the SUBSYS_LOWLEVEL subsystem code.
*/
OPCODE_LOWLEVEL_TEST_LOOPBACK = 18,
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE = 19,
OPCODE_LOWLEVEL_GET_LOOPBACK_MODE = 20
};
-enum LLDP_SUBSYSTEM_OPCODES {
+enum LLDP_SUBSYS_OPCODES {
/* Opcodes used for LLDP susbsytem for configuring the LLDP state machines. */
OPCODE_LLDP_GET_CFG = 1,
OPCODE_LLDP_SET_CFG = 2,
OPCODE_LLDP_GET_STATS = 3
};
-enum DCBX_SUBSYSTEM_OPCODES {
+enum DCBX_SUBSYS_OPCODES {
/* Opcodes used for DCBX. */
OPCODE_DCBX_GET_CFG = 1,
OPCODE_DCBX_SET_CFG = 2,
@@ -1601,12 +1538,12 @@ enum DCBX_SUBSYSTEM_OPCODES {
OPCODE_DCBX_SET_MODE = 5
};
-enum DMTF_SUBSYSTEM_OPCODES {
+enum DMTF_SUBSYS_OPCODES {
/* Opcodes used for DCBX subsystem. */
OPCODE_DMTF_EXEC_CLP_CMD = 1
};
-enum DIAG_SUBSYSTEM_OPCODES {
+enum DIAG_SUBSYS_OPCODES {
/* Opcodes used for diag functions common to many subsystems. */
OPCODE_DIAG_RUN_DMA_TEST = 1,
OPCODE_DIAG_RUN_MDIO_TEST = 2,
@@ -1615,7 +1552,7 @@ enum DIAG_SUBSYSTEM_OPCODES {
OPCODE_DIAG_GET_MAC = 5
};
-enum VENDOR_SUBSYSTEM_OPCODES {
+enum VENDOR_SUBSYS_OPCODES {
/* Opcodes used for Vendor subsystem. */
OPCODE_VENDOR_SLI = 1
};
@@ -1756,11 +1693,11 @@ enum MGMT_ADDI_STATUS {
MGMT_ADDI_INVALID_REQUEST = 75
};
-enum NIC_SUBSYSTEM_OPCODES {
+enum NIC_SUBSYS_OPCODES {
/**
* @brief NIC Subsystem Opcodes (see Network SLI-4 manual >= Rev4, v21-2)
* These opcodes are used for configuring the Ethernet interfaces.
- * These opcodes all use the MBX_SUBSYSTEM_NIC subsystem code.
+ * These opcodes all use the SUBSYS_NIC subsystem code.
*/
OPCODE_NIC_CONFIG_RSS = 1,
OPCODE_NIC_CONFIG_ACPI = 2,