Add op commands necessary to control hfa fanspeeds.
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
diff --git a/driver-hashfast.c b/driver-hashfast.c
index 3b1c30e..52099d8 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -24,6 +24,9 @@ int opt_hfa_overheat = HFA_TEMP_OVERHEAT;
int opt_hfa_target = HFA_TEMP_TARGET;
bool opt_hfa_pll_bypass;
bool opt_hfa_dfu_boot;
+int opt_hfa_fan_default = HFA_FAN_DEFAULT;
+int opt_hfa_fan_max = HFA_FAN_MAX;
+int opt_hfa_fan_min = HFA_FAN_MIN;
////////////////////////////////////////////////////////////////////////////////
// Support for the CRC's used in header (CRC-8) and packet body (CRC-32)
@@ -102,7 +105,10 @@ static const struct hfa_cmd hfa_cmds[] = {
{OP_USB_STATS1, "OP_USB_STATS1", C_NULL},
{OP_USB_GWQSTATS, "OP_USB_GWQSTATS", C_HF_GWQSTATS},
{OP_USB_NOTICE, "OP_USB_NOTICE", C_HF_NOTICE},
- {OP_PING, "OP_PING", C_HF_PING}
+ {OP_PING, "OP_PING", C_HF_PING},
+ {OP_CORE_MAP, "OP_CORE_MAP", C_NULL},
+ {OP_VERSION, "OP_VERSION", C_NULL}, // 32
+ {OP_FAN, "OP_FAN", C_HF_FAN}
};
#define HF_USB_CMD_OFFSET (128 - 18)
@@ -110,28 +116,13 @@ static const struct hfa_cmd hfa_cmds[] = {
/* Send an arbitrary frame, consisting of an 8 byte header and an optional
* packet body. */
-
-static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t hdata,
- uint8_t *data, int len)
+static bool __hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, int tx_length,
+ uint8_t *packet)
{
- int tx_length, ret, amount, id = hashfast->device_id;
struct hashfast_info *info = hashfast->device_data;
- uint8_t packet[256];
- struct hf_header *p = (struct hf_header *)packet;
+ int ret, amount, id = hashfast->device_id;
bool retried = false;
- p->preamble = HF_PREAMBLE;
- p->operation_code = hfa_cmds[opcode].cmd;
- p->chip_address = HF_GWQ_ADDRESS;
- p->core_address = 0;
- p->hdata = htole16(hdata);
- p->data_length = len / 4;
- p->crc8 = hfa_crc8(packet);
-
- if (len)
- memcpy(&packet[sizeof(struct hf_header)], data, len);
- tx_length = sizeof(struct hf_header) + len;
-
if (unlikely(hashfast->usbinfo.nodev))
return false;
@@ -160,6 +151,28 @@ retry:
return true;
}
+static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t hdata,
+ uint8_t *data, int len)
+{
+ uint8_t packet[256];
+ struct hf_header *p = (struct hf_header *)packet;
+ int tx_length;
+
+ p->preamble = HF_PREAMBLE;
+ p->operation_code = hfa_cmds[opcode].cmd;
+ p->chip_address = HF_GWQ_ADDRESS;
+ p->core_address = 0;
+ p->hdata = htole16(hdata);
+ p->data_length = len / 4;
+ p->crc8 = hfa_crc8(packet);
+
+ if (len)
+ memcpy(&packet[sizeof(struct hf_header)], data, len);
+ tx_length = sizeof(struct hf_header) + len;
+
+ return (__hfa_send_frame(hashfast, opcode, tx_length, packet));
+}
+
/* Send an already assembled packet, consisting of an 8 byte header which may
* or may not be followed by a packet body. */
@@ -907,6 +920,9 @@ static void *hfa_read(void *arg)
return NULL;
}
+static void hfa_set_fanspeed(struct cgpu_info *hashfast, struct hashfast_info *info,
+ int fanspeed);
+
static bool hfa_prepare(struct thr_info *thr)
{
struct cgpu_info *hashfast = thr->cgpu;
@@ -921,6 +937,7 @@ static bool hfa_prepare(struct thr_info *thr)
get_datestamp(hashfast->init, sizeof(hashfast->init), &now);
hashfast->last_device_valid_work = time(NULL);
info->resets = 0;
+ hfa_set_fanspeed(hashfast, info, opt_hfa_fan_default);
return true;
}
@@ -953,6 +970,28 @@ out:
return ret;
}
+static void hfa_set_fanspeed(struct cgpu_info *hashfast, struct hashfast_info *info,
+ int fanspeed)
+{
+ const uint8_t opcode = HF_USB_CMD(OP_FAN);
+ uint8_t packet[256];
+ struct hf_header *p = (struct hf_header *)packet;
+ const int tx_length = sizeof(struct hf_header);
+ uint16_t hdata;
+
+ info->fanspeed = fanspeed;
+ hdata = fanspeed * 255 / 100; // Fanspeed is in percent, hdata 0-255
+ p->preamble = HF_PREAMBLE;
+ p->operation_code = hfa_cmds[opcode].cmd;
+ p->chip_address = 0xff;
+ p->core_address = 1;
+ p->hdata = htole16(hdata);
+ p->data_length = 0;
+ p->crc8 = hfa_crc8(packet);
+
+ __hfa_send_frame(hashfast, opcode, tx_length, packet);
+}
+
static void hfa_increase_clock(struct cgpu_info *hashfast, struct hashfast_info *info,
int die)
{
diff --git a/driver-hashfast.h b/driver-hashfast.h
index bd74824..acc89b4 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -22,6 +22,9 @@ int opt_hfa_overheat;
int opt_hfa_target;
bool opt_hfa_pll_bypass;
bool opt_hfa_dfu_boot;
+int opt_hfa_fan_default;
+int opt_hfa_fan_max;
+int opt_hfa_fan_min;
#define HASHFAST_MINER_THREADS 1
#define HFA_CLOCK_DEFAULT 550
@@ -29,6 +32,9 @@ bool opt_hfa_dfu_boot;
#define HFA_TEMP_OVERHEAT 90
#define HFA_TEMP_TARGET 85
#define HFA_TEMP_HYSTERESIS 3
+#define HFA_FAN_DEFAULT 33
+#define HFA_FAN_MAX 100
+#define HFA_FAN_MIN 0
// Matching fields for hf_statistics, but large #s for local accumulation, per-die
struct hf_long_statistics {
@@ -116,6 +122,8 @@ struct hashfast_info {
int resets;
int overheat;
double max_temp;
+ int last_max_temp;
+ int fanspeed; // Fanspeed in percent
pthread_t read_thr;
time_t last_restart;
diff --git a/usbutils.h b/usbutils.h
index 4c4f3d3..60e2209 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -386,6 +386,7 @@ struct cg_usb_info {
USB_ADD_COMMAND(C_HF_GWQSTATS, "HFGWQStats") \
USB_ADD_COMMAND(C_HF_NOTICE, "HFNotice") \
USB_ADD_COMMAND(C_HF_PING, "HFPing") \
+ USB_ADD_COMMAND(C_HF_FAN, "HFFan") \
USB_ADD_COMMAND(C_HF_GETHEADER, "HFGetHeader") \
USB_ADD_COMMAND(C_HF_GETDATA, "HFGetData") \
USB_ADD_COMMAND(C_HF_CLEAR_READ, "HFClearRead") \