Author: np
Date: Tue Jul 18 00:50:58 2017
New Revision: 321103
URL: https://svnweb.freebsd.org/changeset/base/321103

Log:
  cxgbe(4): New ioctls to flash bootrom and boot config to the card.
  
  MFC after:    2 weeks
  Sponsored by: Chelsio Communications

Modified:
  head/sys/dev/cxgbe/t4_ioctl.h
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/t4_ioctl.h
==============================================================================
--- head/sys/dev/cxgbe/t4_ioctl.h       Mon Jul 17 23:16:33 2017        
(r321102)
+++ head/sys/dev/cxgbe/t4_ioctl.h       Tue Jul 18 00:50:58 2017        
(r321103)
@@ -57,6 +57,8 @@ enum {
        T4_GET_TRACER,                  /* get information about a tracer */
        T4_SET_TRACER,                  /* program a tracer */
        T4_LOAD_CFG,                    /* copy a config file to card's flash */
+       T4_LOAD_BOOT,                   /* flash boot rom */
+       T4_LOAD_BOOTCFG,                /* flash bootcfg */
 };
 
 struct t4_reg {
@@ -78,6 +80,13 @@ struct t4_data {
        uint8_t *data;
 };
 
+struct t4_bootrom {
+       uint32_t pf_offset;
+       uint32_t pfidx_addr;
+       uint32_t len;
+       uint8_t *data;
+};
+
 struct t4_i2c_data {
        uint8_t port_id;
        uint8_t dev_addr;
@@ -346,4 +355,6 @@ struct t4_tracer {
 #define CHELSIO_T4_GET_TRACER  _IOWR('f', T4_GET_TRACER, struct t4_tracer)
 #define CHELSIO_T4_SET_TRACER  _IOW('f', T4_SET_TRACER, struct t4_tracer)
 #define CHELSIO_T4_LOAD_CFG    _IOW('f', T4_LOAD_CFG, struct t4_data)
+#define CHELSIO_T4_LOAD_BOOT   _IOW('f', T4_LOAD_BOOT, struct t4_bootrom)
+#define CHELSIO_T4_LOAD_BOOTCFG        _IOW('f', T4_LOAD_BOOTCFG, struct 
t4_data)
 #endif

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Mon Jul 17 23:16:33 2017        
(r321102)
+++ head/sys/dev/cxgbe/t4_main.c        Tue Jul 18 00:50:58 2017        
(r321103)
@@ -571,6 +571,8 @@ static int set_tcb_rpl(struct sge_iq *, const struct r
 static int get_sge_context(struct adapter *, struct t4_sge_context *);
 static int load_fw(struct adapter *, struct t4_data *);
 static int load_cfg(struct adapter *, struct t4_data *);
+static int load_boot(struct adapter *, struct t4_bootrom *);
+static int load_bootcfg(struct adapter *, struct t4_data *);
 static int read_card_mem(struct adapter *, int, struct t4_mem_range *);
 static int read_i2c(struct adapter *, struct t4_i2c_data *);
 #ifdef TCP_OFFLOAD
@@ -8852,6 +8854,87 @@ done:
        return (rc);
 }
 
+static int
+load_boot(struct adapter *sc, struct t4_bootrom *br)
+{
+       int rc;
+       uint8_t *br_data = NULL;
+       u_int offset;
+
+       if (br->len > 1024 * 1024)
+               return (EFBIG);
+
+       if (br->pf_offset == 0) {
+               /* pfidx */
+               if (br->pfidx_addr > 7)
+                       return (EINVAL);
+               offset = G_OFFSET(t4_read_reg(sc, PF_REG(br->pfidx_addr,
+                   A_PCIE_PF_EXPROM_OFST)));
+       } else if (br->pf_offset == 1) {
+               /* offset */
+               offset = G_OFFSET(br->pfidx_addr);
+       } else {
+               return (EINVAL);
+       }
+
+       rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldbr");
+       if (rc)
+               return (rc);
+
+       if (br->len == 0) {
+               /* clear */
+               rc = -t4_load_boot(sc, NULL, offset, 0);
+               goto done;
+       }
+
+       br_data = malloc(br->len, M_CXGBE, M_WAITOK);
+       if (br_data == NULL) {
+               rc = ENOMEM;
+               goto done;
+       }
+
+       rc = copyin(br->data, br_data, br->len);
+       if (rc == 0)
+               rc = -t4_load_boot(sc, br_data, offset, br->len);
+
+       free(br_data, M_CXGBE);
+done:
+       end_synchronized_op(sc, 0);
+       return (rc);
+}
+
+static int
+load_bootcfg(struct adapter *sc, struct t4_data *bc)
+{
+       int rc;
+       uint8_t *bc_data = NULL;
+
+       rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldcf");
+       if (rc)
+               return (rc);
+
+       if (bc->len == 0) {
+               /* clear */
+               rc = -t4_load_bootcfg(sc, NULL, 0);
+               goto done;
+       }
+
+       bc_data = malloc(bc->len, M_CXGBE, M_WAITOK);
+       if (bc_data == NULL) {
+               rc = ENOMEM;
+               goto done;
+       }
+
+       rc = copyin(bc->data, bc_data, bc->len);
+       if (rc == 0)
+               rc = -t4_load_bootcfg(sc, bc_data, bc->len);
+
+       free(bc_data, M_CXGBE);
+done:
+       end_synchronized_op(sc, 0);
+       return (rc);
+}
+
 #define MAX_READ_BUF_SIZE (128 * 1024)
 static int
 read_card_mem(struct adapter *sc, int win, struct t4_mem_range *mr)
@@ -9193,6 +9276,12 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t 
                break;
        case CHELSIO_T4_LOAD_CFG:
                rc = load_cfg(sc, (struct t4_data *)data);
+               break;
+       case CHELSIO_T4_LOAD_BOOT:
+               rc = load_boot(sc, (struct t4_bootrom *)data);
+               break;
+       case CHELSIO_T4_LOAD_BOOTCFG:
+               rc = load_bootcfg(sc, (struct t4_data *)data);
                break;
        default:
                rc = ENOTTY;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to