Implement hashfast send header function and add relevant usb op codes to arrays, beginning reset sequence on hashfast detection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
diff --git a/driver-hashfast.c b/driver-hashfast.c
index f835289..e6820e1 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -56,9 +56,11 @@ struct hf_cmd {
enum usb_cmds usb_cmd;
};
+/* Entries in this array need to align with the actual op values specified
+ * in hf_protocol.h */
#define C_NULL C_MAX
static const struct hf_cmd hf_cmds[] = {
- {OP_NULL, "OP_NULL", C_NULL},
+ {OP_NULL, "OP_NULL", C_NULL}, // 0
{OP_ROOT, "OP_ROOT", C_NULL},
{OP_RESET, "OP_RESET", C_HF_RESET},
{OP_PLL_CONFIG, "OP_PLL_CONFIG", C_HF_PLL_CONFIG},
@@ -66,7 +68,7 @@ static const struct hf_cmd hf_cmds[] = {
{OP_READDRESS, "OP_READDRESS", C_NULL},
{OP_HIGHEST, "OP_HIGHEST", C_NULL},
{OP_BAUD, "OP_BAUD", C_HF_BAUD},
- {OP_UNROOT, "OP_UNROOT", C_NULL},
+ {OP_UNROOT, "OP_UNROOT", C_NULL}, // 8
{OP_HASH, "OP_HASH", C_HF_HASH},
{OP_NONCE, "OP_NONCE", C_HF_NONCE},
{OP_ABORT, "OP_ABORT", C_HF_ABORT},
@@ -74,10 +76,25 @@ static const struct hf_cmd hf_cmds[] = {
{OP_GPIO, "OP_GPIO", C_NULL},
{OP_CONFIG, "OP_CONFIG", C_HF_CONFIG},
{OP_STATISTICS, "OP_STATISTICS", C_HF_STATISTICS},
- {OP_GROUP, "OP_GROUP", C_NULL},
- {OP_CLOCKGATE, "OP_CLOCKGATE", C_HF_CLOCKGATE}
+ {OP_GROUP, "OP_GROUP", C_NULL}, // 16
+ {OP_CLOCKGATE, "OP_CLOCKGATE", C_HF_CLOCKGATE},
+
+ {OP_USB_INIT, "OP_USB_INIT", C_HF_USB_INIT}, // 18
+ {OP_GET_TRACE, "OP_GET_TRACE", C_NULL},
+ {OP_LOOPBACK_USB, "OP_LOOPBACK_USB", C_NULL},
+ {OP_LOOPBACK_UART, "OP_LOOPBACK_UART", C_NULL},
+ {OP_DFU, "OP_DFU", C_NULL},
+ {OP_USB_SHUTDOWN, "OP_USB_SHUTDOWN", C_NULL},
+ {OP_DIE_STATUS, "OP_DIE_STATUS", C_HF_DIE_STATUS}, // 24
+ {OP_GWQ_STATUS, "OP_GWQ_STATUS", C_HF_GWQ_STATUS},
+ {OP_WORK_RESTART, "OP_WORK_RESTART", C_HF_WORK_RESTART},
+ {OP_USB_STATS1, "OP_USB_STATS1", C_NULL},
+ {OP_USB_GWQSTATS, "OP_USB_GWQSTATS", C_HF_GWQSTATS}
};
+#define HF_USB_CMD_OFFSET (128 - 18)
+#define HF_USB_CMD(X) (X - HF_USB_CMD_OFFSET)
+
/* Send an arbitrary frame, consisting of an 8 byte header and an optional
* packet body. */
@@ -113,13 +130,67 @@ static int __maybe_unused hashfast_send_frame(struct cgpu_info *hashfast, uint8_
return 0;
}
-static int __maybe_unused hashfast_reset(struct cgpu_info __maybe_unused *hashfast)
+static bool hashfast_send_header(struct cgpu_info *hashfast, struct hf_header *h,
+ int cmd)
{
- return 0;
+ int amount, ret, len;
+
+ len = sizeof(*h);
+ ret = usb_write(hashfast, (char *)h, len, &amount, hf_cmds[cmd].usb_cmd);
+ if (ret < 0 || amount != len) {
+ applog(LOG_WARNING, "HFA%d: send_header: USB Send error, ret %d amount %d vs. length %d",
+ hashfast->device_id, ret, amount, len);
+ return false;
+ }
+ return true;
}
-static bool hashfast_detect_common(struct cgpu_info __maybe_unused *hashfast)
+static bool hashfast_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
{
+ struct hf_usb_init_header usb_init, *hu = &usb_init;
+ struct hf_usb_init_base *db;
+ uint8_t buf[1024];
+ struct hf_header *h = (struct hf_header *)buf;
+ uint8_t hcrc;
+ uint8_t addr;
+ uint16_t hdata;
+
+ info->hash_clock_rate = 550; // Hash clock rate in Mhz
+ // Assemble the USB_INIT request
+ memset(hu, 0, sizeof(*hu));
+ hu->preamble = HF_PREAMBLE;
+ hu->operation_code = OP_USB_INIT;
+ hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE; // Protocol to use
+ hu->hash_clock = info->hash_clock_rate; // Hash clock rate in Mhz
+ hu->crc8 = hf_crc8((uint8_t *)hu);
+ applog(LOG_WARNING, "HFA%d: Sending OP_USB_INIT with GWQ protocol specified",
+ hashfast->device_id);
+
+ if (!hashfast_send_header(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT)))
+ return false;
+
+ return true;
+}
+
+static bool hashfast_detect_common(struct cgpu_info *hashfast)
+{
+ struct hashfast_info *info;
+ bool ret;
+
+ info = calloc(sizeof(struct hashfast_info), 1);
+ if (!info)
+ quit(1, "Failed to calloc hashfast_info in hashfast_detect_common");
+ hashfast->device_data = info;
+ /* hashfast_reset should fill in details for info */
+ ret = hashfast_reset(hashfast, info);
+ if (!ret) {
+ free(info);
+ return false;
+ }
+
+ info->works = calloc(sizeof(struct work *), HF_NUM_SEQUENCE);
+ if (!info->works)
+ quit(1, "Failed to calloc info works in hashfast_detect_common");
return true;
}
@@ -136,7 +207,7 @@ static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices
hashfast = usb_alloc_cgpu(&hashfast_drv, HASHFAST_MINER_THREADS);
if (!hashfast)
- return false;
+ quit(1, "Failed to usb_alloc_cgpu hashfast");
if (!usb_init(hashfast, dev, found)) {
free(hashfast->device_data);
@@ -150,6 +221,7 @@ static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices
hashfast_usb_initialise(hashfast);
add_cgpu(hashfast);
+
return hashfast_detect_common(hashfast);
}
diff --git a/driver-hashfast.h b/driver-hashfast.h
index f9defdf..6f99496 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -17,6 +17,21 @@
#include "hf_protocol.h"
#define HASHFAST_MINER_THREADS 1
+#define HF_NUM_SEQUENCE 256
+
+struct hashfast_info {
+ int asic_count; // # of chips in the chain
+ struct hf_g1_die_data *die_status; // Array of per-die voltage, current, temperature sensor data
+ struct hf_long_statistics *die_statistics; // Array of per-die error counters
+ int hash_clock_rate; // Hash clock rate to use, in Mhz
+ struct hf_usb_init_base usb_init_base; // USB Base information from USB_INIT
+ struct hf_config_data config_data; // Configuration data used from USB_INIT
+
+ struct work **works;
+ uint16_t device_sequence_head; // The most recent sequence number the device dispatched
+ uint16_t device_sequence_tail; // The most recently completed job in the device
+ uint16_t hash_sequence_tail; // Follows device_sequence_tail around to free work
+};
#endif /* USE_HASHFAST */
#endif /* HASHFAST_H */
diff --git a/usbutils.h b/usbutils.h
index 7dbe4eb..b9bab1c 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -354,7 +354,12 @@ struct cg_usb_info {
USB_ADD_COMMAND(C_HF_STATUS, "HFStatus") \
USB_ADD_COMMAND(C_HF_CONFIG, "HFConfig") \
USB_ADD_COMMAND(C_HF_STATISTICS, "HFStatistics") \
- USB_ADD_COMMAND(C_HF_CLOCKGATE, "HFClockGate")
+ USB_ADD_COMMAND(C_HF_CLOCKGATE, "HFClockGate") \
+ USB_ADD_COMMAND(C_HF_USB_INIT, "HFUSBInit") \
+ USB_ADD_COMMAND(C_HF_DIE_STATUS, "HFDieStatus") \
+ USB_ADD_COMMAND(C_HF_GWQ_STATUS, "HFGWQStatus") \
+ USB_ADD_COMMAND(C_HF_WORK_RESTART, "HFWorkRestart") \
+ USB_ADD_COMMAND(C_HF_GWQSTATS, "HFGWQStats")
/* Create usb_cmds enum from USB_PARSE_COMMANDS macro */
enum usb_cmds {