All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Xu, Rosen" <rosen.xu@intel.com>
To: "Huang, Wei" <wei.huang@intel.com>, "dev@dpdk.org" <dev@dpdk.org>,
	"Zhang,  Qi Z" <qi.z.zhang@intel.com>
Cc: "stable@dpdk.org" <stable@dpdk.org>,
	"Zhang, Tianfei" <tianfei.zhang@intel.com>
Subject: Re: [dpdk-dev] [PATCH v7 2/4] raw/ifpga: add fpga property get function
Date: Thu, 7 Jan 2021 05:30:27 +0000	[thread overview]
Message-ID: <BYAPR11MB2901F11FDEC7BB6F7E114B4089AF0@BYAPR11MB2901.namprd11.prod.outlook.com> (raw)
In-Reply-To: <1609830569-6445-3-git-send-email-wei.huang@intel.com>

Hi,

> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Tuesday, January 05, 2021 15:09
> To: dev@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Cc: stable@dpdk.org; Zhang, Tianfei <tianfei.zhang@intel.com>; Huang, Wei
> <wei.huang@intel.com>
> Subject: [PATCH v7 2/4] raw/ifpga: add fpga property get function
> 
> There are three types of property can be got from FPGA, they are
> implemented in below functions:
> 1. ifpga_rawdev_get_fme_property() get property of FME (FPGA
>    Management Engine).
> 2. ifpga_rawdev_get_port_property() get property of FPGA port.
> 3. ifpga_rawdev_get_bmc_property() get property of BMC (Board
>    Management Controller).
> 
> Signed-off-by: Wei Huang <wei.huang@intel.com>
> ---
>  drivers/raw/ifpga/base/ifpga_api.c         |   8 ++
>  drivers/raw/ifpga/base/ifpga_defines.h     |   1 +
>  drivers/raw/ifpga/base/ifpga_feature_dev.c |  21 +++
>  drivers/raw/ifpga/base/ifpga_feature_dev.h |   1 +
>  drivers/raw/ifpga/base/ifpga_fme.c         |  28 +++-
>  drivers/raw/ifpga/base/opae_hw_api.c       |  18 +++
>  drivers/raw/ifpga/base/opae_hw_api.h       |   2 +
>  drivers/raw/ifpga/base/opae_ifpga_hw_api.h |   1 +
>  drivers/raw/ifpga/ifpga_rawdev.c           | 157 +++++++++++++++++++++
>  drivers/raw/ifpga/ifpga_rawdev.h           |  28 ++++
>  10 files changed, 263 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/raw/ifpga/base/ifpga_api.c
> b/drivers/raw/ifpga/base/ifpga_api.c
> index 1aedf150b..4610ef101 100644
> --- a/drivers/raw/ifpga/base/ifpga_api.c
> +++ b/drivers/raw/ifpga/base/ifpga_api.c
> @@ -229,6 +229,13 @@ static int ifpga_mgr_get_board_info(struct
> opae_manager *mgr,
>  	return 0;
>  }
> 
> +static int ifpga_mgr_get_uuid(struct opae_manager *mgr, struct uuid
> +*uuid) {
> +	struct ifpga_fme_hw *fme = mgr->data;
> +
> +	return fpga_get_pr_uuid(fme, uuid);
> +}
> +
>  static int ifpga_mgr_update_flash(struct opae_manager *mgr, const char
> *image,
>  	u64 *status)
>  {
> @@ -256,6 +263,7 @@ struct opae_manager_ops ifpga_mgr_ops = {
>  	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
>  	.get_sensor_value = ifpga_mgr_get_sensor_value,
>  	.get_board_info = ifpga_mgr_get_board_info,
> +	.get_uuid = ifpga_mgr_get_uuid,
>  	.update_flash = ifpga_mgr_update_flash,
>  	.stop_flash_update = ifpga_mgr_stop_flash_update,
>  	.reload = ifpga_mgr_reload,
> diff --git a/drivers/raw/ifpga/base/ifpga_defines.h
> b/drivers/raw/ifpga/base/ifpga_defines.h
> index 9f0147d1e..dca1518a8 100644
> --- a/drivers/raw/ifpga/base/ifpga_defines.h
> +++ b/drivers/raw/ifpga/base/ifpga_defines.h
> @@ -1727,6 +1727,7 @@ struct opae_board_info {
>  	u8 seu;
>  	u8 ptp;
> 
> +	u32 boot_page;
>  	u32 max10_version;
>  	u32 nios_fw_version;
>  	u32 nums_of_retimer;
> diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> index 0f852a75a..08135137a 100644
> --- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> +++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> @@ -87,6 +87,27 @@ int fpga_get_afu_uuid(struct ifpga_port_hw *port,
> struct uuid *uuid)
>  	return 0;
>  }
> 
> +int fpga_get_pr_uuid(struct ifpga_fme_hw *fme, struct uuid *uuid) {
> +	struct feature_fme_pr *fme_pr;
> +	u64 guidl, guidh;
> +
> +	if (!fme || !uuid)
> +		return -EINVAL;
> +
> +	fme_pr = get_fme_feature_ioaddr_by_index(fme,
> FME_FEATURE_ID_PR_MGMT);
> +
> +	spinlock_lock(&fme->lock);
> +	guidl = readq(&fme_pr->fme_pr_intfc_id_l);
> +	guidh = readq(&fme_pr->fme_pr_intfc_id_h);
> +	spinlock_unlock(&fme->lock);
> +
> +	opae_memcpy(uuid->b, &guidl, sizeof(u64));
> +	opae_memcpy(uuid->b + 8, &guidh, sizeof(u64));
> +
> +	return 0;
> +}
> +
>  /* Mask / Unmask Port Errors by the Error Mask register. */  void
> port_err_mask(struct ifpga_port_hw *port, bool mask)  { diff --git
> a/drivers/raw/ifpga/base/ifpga_feature_dev.h
> b/drivers/raw/ifpga/base/ifpga_feature_dev.h
> index 2b1309b44..b355d22b0 100644
> --- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
> +++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
> @@ -103,6 +103,7 @@ is_port_feature_present(struct ifpga_port_hw *port,
> int index)  }
> 
>  int fpga_get_afu_uuid(struct ifpga_port_hw *port, struct uuid *uuid);
> +int fpga_get_pr_uuid(struct ifpga_fme_hw *fme, struct uuid *uuid);
> 
>  int __fpga_port_disable(struct ifpga_port_hw *port);  void
> __fpga_port_enable(struct ifpga_port_hw *port); diff --git
> a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
> index 34fd9a818..43c7b9c3d 100644
> --- a/drivers/raw/ifpga/base/ifpga_fme.c
> +++ b/drivers/raw/ifpga/base/ifpga_fme.c
> @@ -101,6 +101,24 @@ static int fme_hdr_get_ports_num(struct
> ifpga_fme_hw *fme, u64 *ports_num)
>  	return 0;
>  }
> 
> +static int fme_hdr_get_port_type(struct ifpga_fme_hw *fme, u64
> +*port_type) {
> +	struct feature_fme_header *fme_hdr
> +		= get_fme_feature_ioaddr_by_index(fme,
> FME_FEATURE_ID_HEADER);
> +	struct feature_fme_port pt;
> +	u32 port = (u32)((*port_type >> 32) & 0xffffffff);
> +
> +	pt.csr = readq(&fme_hdr->port[port]);
> +	if (!pt.port_implemented)
> +		return -ENODEV;
> +	if (pt.afu_access_control)
> +		*port_type |= 0x1;
> +	else
> +		*port_type &= ~0x1;
> +
> +	return 0;
> +}
> +
>  static int fme_hdr_get_cache_size(struct ifpga_fme_hw *fme, u64
> *cache_size)  {
>  	struct feature_fme_header *fme_hdr
> @@ -179,6 +197,8 @@ fme_hdr_get_prop(struct ifpga_feature *feature,
> struct feature_prop *prop)
>  		return fme_hdr_get_bitstream_id(fme, &prop->data);
>  	case FME_HDR_PROP_BITSTREAM_METADATA:
>  		return fme_hdr_get_bitstream_metadata(fme, &prop->data);
> +	case FME_HDR_PROP_PORT_TYPE:
> +		return fme_hdr_get_port_type(fme, &prop->data);
>  	}
> 
>  	return -ENOENT;
> @@ -891,13 +911,17 @@ static int fme_get_board_interface(struct
> ifpga_fme_hw *fme)
>  			fme->board_info.nums_of_fvl,
>  			fme->board_info.ports_per_fvl);
> 
> +	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
> +		return -EINVAL;
> +	fme->board_info.boot_page = val & 0x7;
> +
>  	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
>  		return -EINVAL;
> -	fme->board_info.max10_version = val & 0xffffff;
> +	fme->board_info.max10_version = val;
> 
>  	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
>  		return -EINVAL;
> -	fme->board_info.nios_fw_version = val & 0xffffff;
> +	fme->board_info.nios_fw_version = val;
> 
>  	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
>  		fme->board_info.max10_version,
> diff --git a/drivers/raw/ifpga/base/opae_hw_api.c
> b/drivers/raw/ifpga/base/opae_hw_api.c
> index 86ad88f72..11c9887c7 100644
> --- a/drivers/raw/ifpga/base/opae_hw_api.c
> +++ b/drivers/raw/ifpga/base/opae_hw_api.c
> @@ -967,6 +967,24 @@ opae_mgr_get_board_info(struct opae_manager
> *mgr,
>  	return -ENOENT;
>  }
> 
> +/**
> + * opae_mgr_get_uuid -  get manager's UUID.
> + * @mgr: targeted manager
> + * @uuid: a pointer to UUID
> + *
> + * Return: 0 on success, otherwise error code.
> + */
> +int opae_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid) {
> +	if (!mgr || !uuid)
> +		return -EINVAL;
> +
> +	if (mgr->ops && mgr->ops->get_uuid)
> +		return mgr->ops->get_uuid(mgr, uuid);
> +
> +	return -ENOENT;
> +}
> +
>  /**
>   * opae_mgr_update_flash -  update image in flash.
>   * @mgr: targeted manager
> diff --git a/drivers/raw/ifpga/base/opae_hw_api.h
> b/drivers/raw/ifpga/base/opae_hw_api.h
> index c819dc3d2..fcf7d2f6d 100644
> --- a/drivers/raw/ifpga/base/opae_hw_api.h
> +++ b/drivers/raw/ifpga/base/opae_hw_api.h
> @@ -55,6 +55,7 @@ struct opae_manager_ops {
>  			unsigned int *value);
>  	int (*get_board_info)(struct opae_manager *mgr,
>  			struct opae_board_info **info);
> +	int (*get_uuid)(struct opae_manager *mgr, struct uuid *uuid);
>  	int (*update_flash)(struct opae_manager *mgr, const char *image,
>  			u64 *status);
>  	int (*stop_flash_update)(struct opae_manager *mgr, int force); @@
> -360,6 +361,7 @@ int opae_manager_eth_group_read_reg(struct
> opae_manager *mgr, u8 group_id,
>  		u8 type, u8 index, u16 addr, u32 *data);  int
> opae_mgr_get_board_info(struct opae_manager *mgr,
>  		struct opae_board_info **info);
> +int opae_mgr_get_uuid(struct opae_manager *mgr, struct uuid *uuid);
>  int opae_mgr_update_flash(struct opae_manager *mgr, const char *image,
>  		uint64_t *status);
>  int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force); diff
> --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
> b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
> index bab33862e..ffdbebf70 100644
> --- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
> +++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
> @@ -61,6 +61,7 @@ struct feature_prop {
>  #define FME_HDR_PROP_SOCKET_ID		0x5	/* RDONLY */
>  #define FME_HDR_PROP_BITSTREAM_ID		0x6	/* RDONLY */
>  #define FME_HDR_PROP_BITSTREAM_METADATA	0x7	/* RDONLY */
> +#define FME_HDR_PROP_PORT_TYPE		0x8	/* RDWR */
> 
>  /* FME error reporting feature's properties */
>  /* FME error reporting properties format */ diff --git
> a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
> index 660ea2051..8dd566e44 100644
> --- a/drivers/raw/ifpga/ifpga_rawdev.c
> +++ b/drivers/raw/ifpga/ifpga_rawdev.c
> @@ -1738,6 +1738,163 @@
> RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg,
>  	"port=<int> "
>  	"afu_bts=<path>");
> 
> +int ifpga_rawdev_get_fme_property(struct rte_rawdev *dev,
> +	ifpga_fme_property *prop)
> +{
> +	struct opae_adapter *adapter = NULL;
> +	struct ifpga_fme_hw *fme = NULL;
> +	struct opae_board_info *info = NULL;
> +	struct feature_prop fp;
> +	struct uuid pr_id;
> +	int ret = 0;
> +
> +	if (!dev) {
> +		IFPGA_RAWDEV_PMD_ERR("rawdev is invalid");
> +		return -EINVAL;
> +	}
> +
> +	adapter = ifpga_rawdev_get_priv(dev);
> +	if (!adapter) {
> +		IFPGA_RAWDEV_PMD_ERR("adapter is invalid");
> +		return -ENODEV;
> +	}
> +
> +	if (!adapter->mgr || !adapter->mgr->data) {
> +		IFPGA_RAWDEV_PMD_ERR("manager is invalid");
> +		return -ENODEV;
> +	}
> +
> +	ret = opae_mgr_get_board_info(adapter->mgr, &info);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get board info");
> +		return ret;
> +	}
> +	prop->boot_page = info->boot_page;
> +
> +	fme = adapter->mgr->data;
> +	fp.feature_id = FME_FEATURE_ID_HEADER;
> +	fp.prop_id = FME_HDR_PROP_PORTS_NUM;
> +	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get property %u from
> FME",
> +			FME_HDR_PROP_PORTS_NUM);
> +		return ret;
> +	}
> +	prop->num_ports = fp.data;
> +
> +	fp.prop_id = FME_HDR_PROP_BITSTREAM_ID;
> +	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get property %u from
> FME",
> +			FME_HDR_PROP_BITSTREAM_ID);
> +		return ret;
> +	}
> +	prop->bitstream_id = fp.data;
> +
> +	fp.prop_id = FME_HDR_PROP_BITSTREAM_METADATA;
> +	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get property %u from
> FME",
> +			FME_HDR_PROP_BITSTREAM_METADATA);
> +		return ret;
> +	}
> +	prop->bitstream_metadata = fp.data;
> +
> +	ret = opae_mgr_get_uuid(adapter->mgr, &pr_id);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get PR ID from FME");
> +		return ret;
> +	}
> +	memcpy(prop->pr_id.b, pr_id.b, sizeof(ifpga_uuid));
> +
> +	return 0;
> +}
> +
> +int ifpga_rawdev_get_port_property(struct rte_rawdev *dev, uint32_t port,
> +	ifpga_port_property *prop)
> +{
> +	struct opae_adapter *adapter = NULL;
> +	struct ifpga_fme_hw *fme = NULL;
> +	struct feature_prop fp;
> +	struct opae_accelerator *acc = NULL;
> +	struct uuid afu_id;
> +	int ret = 0;
> +
> +	if (!dev) {
> +		IFPGA_RAWDEV_PMD_ERR("rawdev is invalid");
> +		return -EINVAL;
> +	}
> +
> +	adapter = ifpga_rawdev_get_priv(dev);
> +	if (!adapter) {
> +		IFPGA_RAWDEV_PMD_ERR("adapter is invalid");
> +		return -ENODEV;
> +	}
> +
> +	if (!adapter->mgr || !adapter->mgr->data) {
> +		IFPGA_RAWDEV_PMD_ERR("manager is invalid");
> +		return -ENODEV;
> +	}
> +
> +	fme = adapter->mgr->data;
> +	fp.feature_id = FME_FEATURE_ID_HEADER;
> +	fp.prop_id = FME_HDR_PROP_PORT_TYPE;
> +	fp.data = port;
> +	fp.data <<= 32;
> +	ret = ifpga_get_prop(fme->parent, FEATURE_FIU_ID_FME, 0, &fp);
> +	if (ret)
> +		return ret;
> +	prop->type = fp.data & 0xffffffff;
> +
> +	if (prop->type == 0) {
> +		acc = opae_adapter_get_acc(adapter, port);
> +		ret = opae_acc_get_uuid(acc, &afu_id);
> +		if (ret) {
> +			IFPGA_RAWDEV_PMD_ERR("Failed to get AFU ID
> from port %u",
> +				port);
> +			return ret;
> +		}
> +		memcpy(prop->afu_id.b, afu_id.b, sizeof(ifpga_uuid));
> +	}
> +
> +	return 0;
> +}
> +
> +int ifpga_rawdev_get_bmc_property(struct rte_rawdev *dev,
> +	ifpga_bmc_property *prop)
> +{
> +	struct opae_adapter *adapter = NULL;
> +	struct opae_board_info *info = NULL;
> +	int ret = 0;
> +
> +	if (!dev) {
> +		IFPGA_RAWDEV_PMD_ERR("rawdev is invalid");
> +		return -EINVAL;
> +	}
> +
> +	adapter = ifpga_rawdev_get_priv(dev);
> +	if (!adapter) {
> +		IFPGA_RAWDEV_PMD_ERR("adapter is invalid");
> +		return -ENODEV;
> +	}
> +
> +	if (!adapter->mgr) {
> +		IFPGA_RAWDEV_PMD_ERR("manager is invalid");
> +		return -ENODEV;
> +	}
> +
> +	ret = opae_mgr_get_board_info(adapter->mgr, &info);
> +	if (ret) {
> +		IFPGA_RAWDEV_PMD_ERR("Failed to get board info");
> +		return ret;
> +	}
> +
> +	prop->bmc_version = info->max10_version;
> +	prop->fw_version = info->nios_fw_version;
> +
> +	return 0;
> +}
> +
>  int ifpga_rawdev_update_flash(struct rte_rawdev *dev, const char *image,
>  	uint64_t *status)
>  {
> diff --git a/drivers/raw/ifpga/ifpga_rawdev.h
> b/drivers/raw/ifpga/ifpga_rawdev.h
> index bf74a5eb3..d4be7913d 100644
> --- a/drivers/raw/ifpga/ifpga_rawdev.h
> +++ b/drivers/raw/ifpga/ifpga_rawdev.h
> @@ -67,6 +67,28 @@ enum ifpga_irq_type {
>  	IFPGA_AFU_IRQ = 1,
>  };
> 
> +typedef struct {
> +	uint8_t b[16];
> +} ifpga_uuid;
> +
> +typedef struct {
> +	uint32_t boot_page;
> +	uint32_t num_ports;
> +	uint64_t bitstream_id;
> +	uint64_t bitstream_metadata;
> +	ifpga_uuid pr_id;
> +} ifpga_fme_property;
> +
> +typedef struct {
> +	ifpga_uuid afu_id;
> +	uint32_t type;   /* AFU memory access control type */
> +} ifpga_port_property;
> +
> +typedef struct {
> +	uint32_t bmc_version;
> +	uint32_t fw_version;
> +} ifpga_bmc_property;
> +
>  int
>  ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id,
>  		enum ifpga_irq_type type, int vec_start, int count, @@ -76,6
> +98,12 @@ int  ifpga_unregister_msix_irq(enum ifpga_irq_type type,
>  		int vec_start, rte_intr_callback_fn handler, void *arg);
> 
> +int ifpga_rawdev_get_fme_property(struct rte_rawdev *dev,
> +	ifpga_fme_property *prop);
> +int ifpga_rawdev_get_port_property(struct rte_rawdev *dev, uint32_t port,
> +	ifpga_port_property *prop);
> +int ifpga_rawdev_get_bmc_property(struct rte_rawdev *dev,
> +	ifpga_bmc_property *prop);
>  int ifpga_rawdev_update_flash(struct rte_rawdev *dev, const char *image,
>  	uint64_t *status);
>  int ifpga_rawdev_stop_flash_update(struct rte_rawdev *dev, int force);
> --
> 2.29.2

Reviewed-by: Rosen Xu <rosen.xu@intel.com>

  reply	other threads:[~2021-01-07  5:31 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-05  7:09 [dpdk-dev] [PATCH v7 0/4] raw/ifpga: add extra OPAE APIs Wei Huang
2021-01-05  7:09 ` [dpdk-dev] [PATCH v7 1/4] raw/ifpga: add fpga rsu function Wei Huang
2021-01-06  1:02   ` Zhang, Tianfei
2021-01-07  5:32   ` Xu, Rosen
2021-01-05  7:09 ` [dpdk-dev] [PATCH v7 2/4] raw/ifpga: add fpga property get function Wei Huang
2021-01-07  5:30   ` Xu, Rosen [this message]
2021-01-05  7:09 ` [dpdk-dev] [PATCH v7 3/4] raw/ifpga: add opae API for Cyborg Wei Huang
2021-01-07  5:31   ` Xu, Rosen
2021-01-05  7:09 ` [dpdk-dev] [PATCH v7 4/4] examples/ifpga: add example for opae ifpga API Wei Huang
2021-01-07  5:34   ` Xu, Rosen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BYAPR11MB2901F11FDEC7BB6F7E114B4089AF0@BYAPR11MB2901.namprd11.prod.outlook.com \
    --to=rosen.xu@intel.com \
    --cc=dev@dpdk.org \
    --cc=qi.z.zhang@intel.com \
    --cc=stable@dpdk.org \
    --cc=tianfei.zhang@intel.com \
    --cc=wei.huang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.