Update knc-asic library to current version
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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
diff --git a/knc-asic.c b/knc-asic.c
index 12fc80e..8aef28b 100644
--- a/knc-asic.c
+++ b/knc-asic.c
@@ -1,5 +1,5 @@
/*
- * library for KnCminer devices
+ * cgminer driver for KnCminer Neptune devices
*
* Copyright 2014 KnCminer
*
@@ -29,27 +29,6 @@
#include "knc-asic.h"
-
-#define MAX_ASICS 6
-#define DIES_PER_ASIC 4
-#define MAX_CORES_PER_DIE 360
-#define WORKS_PER_CORE 2
-
-/* ASIC Command codes */
-#define ASIC_CMD_GETINFO 0x80
-#define ASIC_CMD_SETWORK 0x81
-#define ASIC_CMD_SETWORK_CLEAN 0x83 /* Neptune */
-#define ASIC_CMD_HALT 0x83 /* Jupiter */
-#define ASIC_CMD_REPORT 0x82
-
-#define ASIC_ACK_CRC (1<<5)
-#define ASIC_ACK_ACCEPT (1<<2)
-#define ASIC_ACK_MASK (~(ASIC_ACK_CRC|ASIC_ACK_ACCEPT))
-#define ASIC_ACK_MATCH ((1<<7)|(1<<0))
-
-#define ASIC_VERSION_JUPITER 0xa001
-#define ASIC_VERSION_NEPTUNE 0xa002
-
/* Control Commands
*
* SPI command on channel. 1-
@@ -104,9 +83,10 @@
*
* cores 16 bits
* version 16 bits
- * reserved 32 bits (Neptune)
- * reserved 32 bits (Neptune)
- * reserved cores * 2 bits (Neptune) rounded up to bytes
+ * reserved 64 bits (Neptune)
+ * core_status cores * 2 bits (Neptune) rounded up to bytes
+ * 1' want_work
+ * 1' has_report (unreliable)
*
* REPORT
*
@@ -270,16 +250,16 @@ static void knc_prepare_core_command(uint8_t *request, int command, int die, int
int knc_prepare_report(uint8_t *request, int die, int core)
{
- knc_prepare_core_command(request, ASIC_CMD_REPORT, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_REPORT, die, core);
return 4;
}
int knc_prepare_neptune_setwork(uint8_t *request, int die, int core, int slot, struct work *work, int clean)
{
if (!clean)
- knc_prepare_core_command(request, ASIC_CMD_SETWORK, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_SETWORK, die, core);
else
- knc_prepare_core_command(request, ASIC_CMD_SETWORK_CLEAN, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_SETWORK_CLEAN, die, core);
request[4] = slot | 0xf0;
if (work)
knc_prepare_neptune_work(request + 4 + 1, work);
@@ -290,7 +270,7 @@ int knc_prepare_neptune_setwork(uint8_t *request, int die, int core, int slot, s
int knc_prepare_jupiter_setwork(uint8_t *request, int die, int core, int slot, struct work *work)
{
- knc_prepare_core_command(request, ASIC_CMD_SETWORK, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_SETWORK, die, core);
request[4] = slot | 0xf0;
if (work)
knc_prepare_jupiter_work(request + 4 + 1, work);
@@ -301,13 +281,13 @@ int knc_prepare_jupiter_setwork(uint8_t *request, int die, int core, int slot, s
int knc_prepare_jupiter_halt(uint8_t *request, int die, int core)
{
- knc_prepare_core_command(request, ASIC_CMD_HALT, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_HALT, die, core);
return 4;
}
int knc_prepare_neptune_halt(uint8_t *request, int die, int core)
{
- knc_prepare_core_command(request, ASIC_CMD_HALT, die, core);
+ knc_prepare_core_command(request, KNC_ASIC_CMD_HALT, die, core);
request[4] = 0 | 0xf0;
memset(request + 4 + 1, 0, 6*4 + 3*4 + 8*4);
return 4 + 1 + 6*4 + 3*4 + 8*4;
@@ -354,11 +334,11 @@ int knc_verify_response(uint8_t *rxbuf, int len, int response_length)
}
uint8_t ack = rxbuf[len - 4]; /* 2 + MAX(4 + response_length, request_length) + 4; */
- if ((ack & ASIC_ACK_MASK) != ASIC_ACK_MATCH)
+ if ((ack & KNC_ASIC_ACK_MASK) != KNC_ASIC_ACK_MATCH)
ret |= KNC_ERR_ACK;
- if ((ack & ASIC_ACK_CRC))
+ if ((ack & KNC_ASIC_ACK_CRC))
ret |= KNC_ERR_CRCACK;
- if ((ack & ASIC_ACK_ACCEPT))
+ if ((ack & KNC_ASIC_ACK_ACCEPT))
ret |= KNC_ACCEPTED;
return ret;
}
@@ -380,33 +360,53 @@ int knc_syncronous_transfer(void *ctx, int channel, int request_length, const ui
return knc_verify_response(rxbuf, len, response_length);
}
-int knc_detect_die(void *ctx, int channel, int die, struct knc_die_info *die_info)
+int knc_decode_info(uint8_t *response, struct knc_die_info *die_info)
{
- uint8_t get_info[4] = { ASIC_CMD_GETINFO, die, 0, 0 };
- int response_len = 2 + 2 + 4 + 4 + (MAX_CORES_PER_DIE*2 + 7) / 8;
- uint8_t response[response_len];
- int status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
int cores_in_die = response[0]<<8 | response[1];
int version = response[2]<<8 | response[3];
- if (version == ASIC_VERSION_NEPTUNE && cores_in_die < MAX_CORES_PER_DIE) {
- applog(LOG_DEBUG, "KnC %d-%d: Looks like a NEPTUNE die with %d cores", channel, die, cores_in_die);
- /* Try again with right response size */
- response_len = 2 + 2 + 4 + 4 + (cores_in_die*2 + 7) / 8;
- status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
- }
- if (version == ASIC_VERSION_JUPITER) {
- applog(LOG_INFO, "KnC %d-%d: Found JUPITER die with %d cores", channel, die, cores_in_die);
+ if (version == KNC_ASIC_VERSION_JUPITER && cores_in_die <= 48) {
die_info->version = KNC_VERSION_JUPITER;
die_info->cores = cores_in_die;
+ memset(die_info->want_work, -1, cores_in_die);
return 0;
- } else if (version == ASIC_VERSION_NEPTUNE && status == 0) {
- applog(LOG_INFO, "KnC %d-%d: Found NEPTUNE die with %d cores", channel, die, cores_in_die);
+ } else if (version == KNC_ASIC_VERSION_NEPTUNE && cores_in_die <= KNC_MAX_CORES_PER_DIE) {
die_info->version = KNC_VERSION_NEPTUNE;
die_info->cores = cores_in_die;
+ int core;
+ for (core = 0; core < cores_in_die; core++)
+ die_info->want_work[core] = ((response[12 + core/4] >> ((3-(core % 4)) * 2)) >> 1) & 1;
return 0;
} else {
- applog(LOG_DEBUG, "KnC %d-%d: No KnC chip found", channel, die);
return -1;
}
}
+int knc_detect_die(void *ctx, int channel, int die, struct knc_die_info *die_info)
+{
+ uint8_t get_info[4] = { KNC_ASIC_CMD_GETINFO, die, 0, 0 };
+ int response_len = 2 + 2 + 4 + 4 + (KNC_MAX_CORES_PER_DIE*2 + 7) / 8;
+ uint8_t response[response_len];
+ int status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
+ /* Workaround for pre-ASIC version */
+ int cores_in_die = response[0]<<8 | response[1];
+ int version = response[2]<<8 | response[3];
+ if (version == KNC_ASIC_VERSION_NEPTUNE && cores_in_die < KNC_MAX_CORES_PER_DIE) {
+ applog(LOG_DEBUG, "KnC %d-%d: Looks like a NEPTUNE die with %d cores", channel, die, cores_in_die);
+ /* Try again with right response size */
+ response_len = 2 + 2 + 4 + 4 + (cores_in_die*2 + 7) / 8;
+ status = knc_syncronous_transfer(ctx, channel, 4, get_info, response_len, response);
+ }
+ int rc = -1;
+ if (version == KNC_ASIC_VERSION_JUPITER || status == 0)
+ rc = knc_decode_info(response, die_info);
+ if (rc == 0)
+ applog(LOG_INFO, "KnC %d-%d: Found %s die with %d cores", channel, die,
+ die_info->version == KNC_VERSION_NEPTUNE ? "NEPTUNE" :
+ die_info->version == KNC_VERSION_JUPITER ? "JUPITER" :
+ "UNKNOWN",
+ cores_in_die);
+ else
+ applog(LOG_DEBUG, "KnC %d-%d: No KnC chip found", channel, die);
+ return rc;
+}
+
diff --git a/knc-asic.h b/knc-asic.h
index 0cf0c35..5f85cab 100644
--- a/knc-asic.h
+++ b/knc-asic.h
@@ -4,12 +4,34 @@
#include <stdint.h>
#include "miner.h"
+/* ASIC Command codes */
+#define KNC_ASIC_CMD_GETINFO 0x80
+#define KNC_ASIC_CMD_SETWORK 0x81
+#define KNC_ASIC_CMD_SETWORK_CLEAN 0x83 /* Neptune */
+#define KNC_ASIC_CMD_HALT 0x83 /* Jupiter */
+#define KNC_ASIC_CMD_REPORT 0x82
+
+/* Status byte */
+#define KNC_ASIC_ACK_CRC (1<<5)
+#define KNC_ASIC_ACK_ACCEPT (1<<2)
+#define KNC_ASIC_ACK_MASK (~(KNC_ASIC_ACK_CRC|KNC_ASIC_ACK_ACCEPT))
+#define KNC_ASIC_ACK_MATCH ((1<<7)|(1<<0))
+
+/* Version word */
+#define KNC_ASIC_VERSION_JUPITER 0xa001
+#define KNC_ASIC_VERSION_NEPTUNE 0xa002
+
+/* Limits of current chips & I/O board */
+#define KNC_MAX_CORES_PER_DIE 360
+#define KNC_MAX_ASICS 6
+
struct knc_die_info {
enum {
KNC_VERSION_UNKNOWN = 0,
KNC_VERSION_JUPITER,
KNC_VERSION_NEPTUNE
} version;
+ char want_work[KNC_MAX_CORES_PER_DIE];
int cores;
};
@@ -19,6 +41,8 @@ int knc_prepare_jupiter_setwork(uint8_t *request, int die, int core, int slot, s
int knc_prepare_jupiter_halt(uint8_t *request, int die, int core);
int knc_prepare_neptune_halt(uint8_t *request, int die, int core);
+int knc_decode_info(uint8_t *response, struct knc_die_info *die_info);
+
void knc_prepare_neptune_message(int request_length, const uint8_t *request, uint8_t *buffer);
#define KNC_ACCEPTED (1<<0)