|
@@ -1,6 +1,6 @@
|
|
/*
|
|
/*
|
|
* Copyright 2013-2014 Con Kolivas <kernel@kolivas.org>
|
|
* Copyright 2013-2014 Con Kolivas <kernel@kolivas.org>
|
|
- * Copyright 2014 LKETC Integrated Systems Limited
|
|
|
|
|
|
+ * Copyright 2014 Lketc Integrated Systems Limited
|
|
* Copyright 2014 Dominik Lehner
|
|
* Copyright 2014 Dominik Lehner
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
@@ -43,7 +43,7 @@
|
|
|
|
|
|
// Configuration options
|
|
// Configuration options
|
|
extern bool opt_lketc_debug;
|
|
extern bool opt_lketc_debug;
|
|
-extern int opt_lketc_chips_count; // number of Zeus chips chained together
|
|
|
|
|
|
+extern int opt_lketc_chips_count; // number of Lketc chips chained together
|
|
extern int opt_lketc_chip_clk; // frequency to run chips with
|
|
extern int opt_lketc_chip_clk; // frequency to run chips with
|
|
extern bool opt_lketc_nocheck_golden; // bypass hashrate check
|
|
extern bool opt_lketc_nocheck_golden; // bypass hashrate check
|
|
|
|
|
|
@@ -60,12 +60,8 @@ static struct name_chip_map {
|
|
char *model_name;
|
|
char *model_name;
|
|
int chips_count;
|
|
int chips_count;
|
|
} lketc_models[] = {
|
|
} lketc_models[] = {
|
|
- { "Blizzard", 6 },
|
|
|
|
- //{ "Cyclone", 96 }, // model renamed??
|
|
|
|
- { "Hurricane X2", 48 },
|
|
|
|
- { "Hurricane X3", 64 },
|
|
|
|
- { "Thunder X2", 96 },
|
|
|
|
- { "Thunder X3", 128 },
|
|
|
|
|
|
+ { "Stick", 1 },
|
|
|
|
+ { "Dragon", 2 },
|
|
{ NULL, 0 }
|
|
{ NULL, 0 }
|
|
};
|
|
};
|
|
|
|
|
|
@@ -329,7 +325,7 @@ static void lketc_get_device_options(const char *devid, int *chips_count, int *c
|
|
switch (index++) {
|
|
switch (index++) {
|
|
case 1: // chip count
|
|
case 1: // chip count
|
|
if (lval < LKETC_MIN_CHIPS || lval > LKETC_MAX_CHIPS) {
|
|
if (lval < LKETC_MIN_CHIPS || lval > LKETC_MAX_CHIPS) {
|
|
- applog(LOG_ERR, "Invalid chip count %ld for Zeus device %s",
|
|
|
|
|
|
+ applog(LOG_ERR, "Invalid chip count %ld for Lketc device %s",
|
|
lval, devid);
|
|
lval, devid);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -337,7 +333,7 @@ static void lketc_get_device_options(const char *devid, int *chips_count, int *c
|
|
break;
|
|
break;
|
|
case 2: // clock
|
|
case 2: // clock
|
|
if (lval < LKETC_CLK_MIN || lval > LKETC_CLK_MAX) {
|
|
if (lval < LKETC_CLK_MIN || lval > LKETC_CLK_MAX) {
|
|
- applog(LOG_ERR, "Invalid clock speed %ld for Zeus device %s",
|
|
|
|
|
|
+ applog(LOG_ERR, "Invalid clock speed %ld for Lketc device %s",
|
|
lval, devid);
|
|
lval, devid);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -395,7 +391,7 @@ static bool lketc_initialize_cp2102(struct cgpu_info *lketc)
|
|
CP210X_VALUE_DATA, interface, C_SETDATA))
|
|
CP210X_VALUE_DATA, interface, C_SETDATA))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- // Zeusminers have baud hardcoded to 115200, and reject baud commands, even to same value
|
|
|
|
|
|
+ // Lketcminers have baud hardcoded to 115200, and reject baud commands, even to same value
|
|
// Set the baud
|
|
// Set the baud
|
|
//if (lketc_usb_control_transfer_data(lketc, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD,
|
|
//if (lketc_usb_control_transfer_data(lketc, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD,
|
|
// 0, interface, &baudrate, sizeof(baudrate), C_SETBAUD))
|
|
// 0, interface, &baudrate, sizeof(baudrate), C_SETBAUD))
|
|
@@ -404,15 +400,9 @@ static bool lketc_initialize_cp2102(struct cgpu_info *lketc)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-static bool lketc_initialize_ftdi(struct cgpu_info *lketc)
|
|
|
|
-{
|
|
|
|
- int interface = usb_interface(lketc);
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static bool lketc_initialize_usb(struct cgpu_info *lketc)
|
|
static bool lketc_initialize_usb(struct cgpu_info *lketc)
|
|
{
|
|
{
|
|
|
|
+ struct LKETC_INFO *info = lketc->device_data;
|
|
enum sub_ident ident;
|
|
enum sub_ident ident;
|
|
|
|
|
|
if (lketc->usbinfo.nodev)
|
|
if (lketc->usbinfo.nodev)
|
|
@@ -422,6 +412,7 @@ static bool lketc_initialize_usb(struct cgpu_info *lketc)
|
|
|
|
|
|
switch (ident) {
|
|
switch (ident) {
|
|
case IDENT_LKE:
|
|
case IDENT_LKE:
|
|
|
|
+ info->read_data_offset = 0;
|
|
return lketc_initialize_cp2102(lketc);
|
|
return lketc_initialize_cp2102(lketc);
|
|
default:
|
|
default:
|
|
applog(LOG_ERR, "lketc_initialize_usb called on wrong device, ident=%d", ident);
|
|
applog(LOG_ERR, "lketc_initialize_usb called on wrong device, ident=%d", ident);
|
|
@@ -468,7 +459,7 @@ static struct cgpu_info *lketc_detect_one_usb(struct libusb_device *dev, struct
|
|
|
|
|
|
lketc->usbdev->usb_type = USB_TYPE_STD;
|
|
lketc->usbdev->usb_type = USB_TYPE_STD;
|
|
if (!lketc_initialize_usb(lketc)) {
|
|
if (!lketc_initialize_usb(lketc)) {
|
|
- applog(LOG_ERR, "Failed to initialize Zeus USB-UART interface");
|
|
|
|
|
|
+ applog(LOG_ERR, "Failed to initialize Lketc USB-UART interface");
|
|
goto alldealloc;
|
|
goto alldealloc;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -529,12 +520,12 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
//chips_count_max = opt_lketc_chips_count_max;
|
|
//chips_count_max = opt_lketc_chips_count_max;
|
|
|
|
|
|
if (initial_startup_phase)
|
|
if (initial_startup_phase)
|
|
- applog(LOG_INFO, "Zeus Detect: Attempting to open %s", devpath);
|
|
|
|
|
|
+ applog(LOG_INFO, "Lketc Detect: Attempting to open %s", devpath);
|
|
|
|
|
|
fd = lketc_serial_open_detect(devpath, baud, true);
|
|
fd = lketc_serial_open_detect(devpath, baud, true);
|
|
if (unlikely(fd == -1)) {
|
|
if (unlikely(fd == -1)) {
|
|
if (initial_startup_phase)
|
|
if (initial_startup_phase)
|
|
- applog(LOG_ERR, "Zeus Detect: Failed to open %s", devpath);
|
|
|
|
|
|
+ applog(LOG_ERR, "Lketc Detect: Failed to open %s", devpath);
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -542,7 +533,7 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
|
|
|
|
// from 150M step to the high or low speed. we need to add delay and resend to init chip
|
|
// from 150M step to the high or low speed. we need to add delay and resend to init chip
|
|
if (chip_clk > 150)
|
|
if (chip_clk > 150)
|
|
- freqcode_init = lketc_clk_to_freqcode(165);
|
|
|
|
|
|
+ freqcode_init = lketc_clk_to_freqcode(170);
|
|
else
|
|
else
|
|
freqcode_init = lketc_clk_to_freqcode(139);
|
|
freqcode_init = lketc_clk_to_freqcode(139);
|
|
|
|
|
|
@@ -592,7 +583,7 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
nonce = be32toh(nonce);
|
|
nonce = be32toh(nonce);
|
|
|
|
|
|
if (nonce != golden_nonce_val) {
|
|
if (nonce != golden_nonce_val) {
|
|
- applog(LOG_ERR, "Zeus Detect: "
|
|
|
|
|
|
+ applog(LOG_ERR, "Lketc Detect: "
|
|
"Test failed at %s: got %08x, should be: %08x",
|
|
"Test failed at %s: got %08x, should be: %08x",
|
|
devpath, nonce, golden_nonce_val);
|
|
devpath, nonce, golden_nonce_val);
|
|
return false;
|
|
return false;
|
|
@@ -608,7 +599,7 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
golden_speed_per_core = (((chip_clk * 2.) / 3.) * 1024.) / 8.;
|
|
golden_speed_per_core = (((chip_clk * 2.) / 3.) * 1024.) / 8.;
|
|
}
|
|
}
|
|
|
|
|
|
- /* We have a real Zeus miner! */
|
|
|
|
|
|
+ /* We have a real Lketc miner! */
|
|
struct cgpu_info *lketc;
|
|
struct cgpu_info *lketc;
|
|
struct LKETC_INFO *info;
|
|
struct LKETC_INFO *info;
|
|
|
|
|
|
@@ -626,10 +617,10 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
lketc->deven = DEV_ENABLED;
|
|
lketc->deven = DEV_ENABLED;
|
|
lketc->threads = 1;
|
|
lketc->threads = 1;
|
|
|
|
|
|
- applog(LOG_NOTICE, "Found Zeus at %s, mark as %d",
|
|
|
|
|
|
+ applog(LOG_NOTICE, "Found Lketc at %s, mark as %d",
|
|
devpath, lketc->device_id);
|
|
devpath, lketc->device_id);
|
|
|
|
|
|
- applog(LOG_INFO, "Zeus: Init: %d baud=%d cores_per_chip=%d chips_count=%d",
|
|
|
|
|
|
+ applog(LOG_INFO, "Lketc: Init: %d baud=%d cores_per_chip=%d chips_count=%d",
|
|
lketc->device_id, baud, cores_per_chip, chips_count);
|
|
lketc->device_id, baud, cores_per_chip, chips_count);
|
|
|
|
|
|
info->device_fd = -1;
|
|
info->device_fd = -1;
|
|
@@ -661,6 +652,7 @@ static bool lketc_detect_one_serial(const char *devpath)
|
|
quit(1, "chips_count_max must be a power of 2");
|
|
quit(1, "chips_count_max must be a power of 2");
|
|
info->chip_clk = chip_clk;
|
|
info->chip_clk = chip_clk;
|
|
info->chips_bit_num = log_2(chips_count_max);
|
|
info->chips_bit_num = log_2(chips_count_max);
|
|
|
|
+ info->read_data_offset = 0;
|
|
|
|
|
|
if (!add_cgpu(lketc))
|
|
if (!add_cgpu(lketc))
|
|
quit(1, "Failed to add_cgpu");
|
|
quit(1, "Failed to add_cgpu");
|
|
@@ -690,23 +682,35 @@ static void lketc_purge_work(struct cgpu_info *lketc)
|
|
static bool lketc_read_response(struct cgpu_info *lketc)
|
|
static bool lketc_read_response(struct cgpu_info *lketc)
|
|
{
|
|
{
|
|
struct LKETC_INFO *info = lketc->device_data;
|
|
struct LKETC_INFO *info = lketc->device_data;
|
|
- unsigned char evtpkt[LKETC_EVENT_PKT_LEN];
|
|
|
|
|
|
+ unsigned char evtpkt[LKETC_READ_BUFFER];
|
|
uint32_t nonce, chip, core;
|
|
uint32_t nonce, chip, core;
|
|
int ret, err;
|
|
int ret, err;
|
|
double duration_s;
|
|
double duration_s;
|
|
bool valid;
|
|
bool valid;
|
|
|
|
|
|
if (using_libusb(info)) {
|
|
if (using_libusb(info)) {
|
|
- err = usb_read_timeout(lketc, (char *)evtpkt, sizeof(evtpkt), &ret, 250, C_GETRESULTS);
|
|
|
|
|
|
+ //err = usb_read_timeout(lketc, (char *)evtpkt, sizeof(evtpkt), &ret, 250, C_GETRESULTS);
|
|
|
|
+ err = usb_read_once(lketc, (char *)evtpkt, sizeof(evtpkt), &ret, C_GETRESULTS);
|
|
|
|
+
|
|
|
|
+#if LKETC_PROTOCOL_DEBUG
|
|
|
|
+ if (opt_lketc_debug) {
|
|
|
|
+ char *hexstr;
|
|
|
|
+ hexstr = bin2hex(evtpkt, ret);
|
|
|
|
+ applog(LOG_DEBUG, "< %s err=%d ret=%d", hexstr, err, ret);
|
|
|
|
+ free(hexstr);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_TIMEOUT) {
|
|
if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_TIMEOUT) {
|
|
applog(LOG_ERR, "%s%d: USB read error: %s",
|
|
applog(LOG_ERR, "%s%d: USB read error: %s",
|
|
lketc->drv->name, lketc->device_id, libusb_error_name(err));
|
|
lketc->drv->name, lketc->device_id, libusb_error_name(err));
|
|
return false;
|
|
return false;
|
|
- } else if (err == LIBUSB_ERROR_TIMEOUT) {
|
|
|
|
- return true;
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (ret < LKETC_EVENT_PKT_LEN + info->read_data_offset)
|
|
|
|
+ return true;
|
|
} else {
|
|
} else {
|
|
- ret = lketc_serial_read(info->device_fd, evtpkt, sizeof(evtpkt), 1, NULL);
|
|
|
|
|
|
+ ret = lketc_serial_read(info->device_fd, evtpkt, LKETC_EVENT_PKT_LEN, 1, NULL);
|
|
if (ret < 0) { // error
|
|
if (ret < 0) { // error
|
|
info->serial_reopen = true;
|
|
info->serial_reopen = true;
|
|
notify_send_work_thread(lketc);
|
|
notify_send_work_thread(lketc);
|
|
@@ -719,7 +723,7 @@ static bool lketc_read_response(struct cgpu_info *lketc)
|
|
|
|
|
|
cgtime(&info->workend);
|
|
cgtime(&info->workend);
|
|
|
|
|
|
- memcpy(&nonce, evtpkt, sizeof(evtpkt));
|
|
|
|
|
|
+ memcpy(&nonce, evtpkt + info->read_data_offset, LKETC_EVENT_PKT_LEN);
|
|
nonce = be32toh(nonce);
|
|
nonce = be32toh(nonce);
|
|
|
|
|
|
mutex_lock(&info->lock);
|
|
mutex_lock(&info->lock);
|
|
@@ -809,6 +813,14 @@ static bool lketc_send_work(struct cgpu_info *lketc, struct work *work)
|
|
rev(cmdpkt + 4, 80);
|
|
rev(cmdpkt + 4, 80);
|
|
|
|
|
|
if (using_libusb(info)) { // in libusb mode we send via usb ;)
|
|
if (using_libusb(info)) { // in libusb mode we send via usb ;)
|
|
|
|
+#if LKETC_PROTOCOL_DEBUG
|
|
|
|
+ if (opt_lketc_debug) {
|
|
|
|
+ char *hexstr;
|
|
|
|
+ hexstr = bin2hex(cmdpkt, sizeof(cmdpkt));
|
|
|
|
+ applog(LOG_DEBUG, "> %s", hexstr);
|
|
|
|
+ free(hexstr);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
if (usb_write(lketc, (char *)cmdpkt, sizeof(cmdpkt), &ret, C_SENDWORK) != LIBUSB_SUCCESS ||
|
|
if (usb_write(lketc, (char *)cmdpkt, sizeof(cmdpkt), &ret, C_SENDWORK) != LIBUSB_SUCCESS ||
|
|
ret != sizeof(cmdpkt))
|
|
ret != sizeof(cmdpkt))
|
|
return false;
|
|
return false;
|
|
@@ -832,7 +844,7 @@ static void *lketc_send_work_thread(void *data)
|
|
struct timeval tv_now, tv_spent, tv_rem;
|
|
struct timeval tv_now, tv_spent, tv_rem;
|
|
int retval;
|
|
int retval;
|
|
|
|
|
|
- snprintf(threadname, sizeof(threadname), "Zeus/%d", lketc->device_id);
|
|
|
|
|
|
+ snprintf(threadname, sizeof(threadname), "Lketc/%d", lketc->device_id);
|
|
RenameThread(threadname);
|
|
RenameThread(threadname);
|
|
applog(LOG_INFO, "%s%d: serial I/O thread running, %s",
|
|
applog(LOG_INFO, "%s%d: serial I/O thread running, %s",
|
|
lketc->drv->name, lketc->device_id, threadname);
|
|
lketc->drv->name, lketc->device_id, threadname);
|
|
@@ -909,7 +921,6 @@ static int lketc_autoscan()
|
|
int found = 0;
|
|
int found = 0;
|
|
applog(LOG_DEBUG, "lketc_autoscan() called");
|
|
applog(LOG_DEBUG, "lketc_autoscan() called");
|
|
found += serial_autodetect_udev(lketc_detect_one_serial, LKETC_USB_ID_MODEL_STR1);
|
|
found += serial_autodetect_udev(lketc_detect_one_serial, LKETC_USB_ID_MODEL_STR1);
|
|
- found += serial_autodetect_udev(lketc_detect_one_serial, LKETC_USB_ID_MODEL_STR2);
|
|
|
|
return found;
|
|
return found;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -978,7 +989,7 @@ static int64_t lketc_scanwork(struct thr_info *thr)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- if (unlikely(lketc_read_response(lketc) < 0)) // reads either from serial or libusb or times out
|
|
|
|
|
|
+ if (unlikely(!lketc_read_response(lketc))) // reads either from serial or libusb or times out
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
if (thr->work_restart || thr->work_update) {
|
|
if (thr->work_restart || thr->work_update) {
|
|
@@ -1134,7 +1145,7 @@ static void lketc_shutdown(struct thr_info *thr)
|
|
|
|
|
|
struct device_drv lketc_drv = {
|
|
struct device_drv lketc_drv = {
|
|
.drv_id = DRIVER_lketc,
|
|
.drv_id = DRIVER_lketc,
|
|
- .dname = "Zeus",
|
|
|
|
|
|
+ .dname = "LKETC",
|
|
.name = "LKE",
|
|
.name = "LKE",
|
|
.max_diff = 32768,
|
|
.max_diff = 32768,
|
|
.drv_detect = lketc_detect,
|
|
.drv_detect = lketc_detect,
|