Commit ff0dbafe804925c93dad5b74a4f040d12a20dcae

Vitalii Demianets 2013-12-22T13:03:50

knc: Bugfix - good shares wrongly reported as HW errors. Root cause of the problem: several work items were assigned the same work_id in the active works queue of the knc driver. Thus when good nonce report arrived from the FPGA, wrong work item was picked up from the queue, and submit_nonce evaluated that as an error. Fix: Limit the work_id counter update rate. Update it only to the number of works actually consumed by the FPGA, not to the number of works send.

diff --git a/driver-knc-spi-fpga.c b/driver-knc-spi-fpga.c
index 112eae2..21745c7 100644
--- a/driver-knc-spi-fpga.c
+++ b/driver-knc-spi-fpga.c
@@ -486,16 +486,15 @@ static void knc_check_disabled_cores(struct knc_state *knc)
 
 static void knc_work_from_queue_to_spi(struct knc_state *knc,
 				       struct active_work *q_work,
-				       struct spi_request *spi_req)
+				       struct spi_request *spi_req, uint32_t work_id)
 {
 	uint32_t *buf_from, *buf_to;
 	int i;
 
 	spi_req->cmd = CMD_SUBMIT_WORK;
 	spi_req->queue_id = 0; /* at the moment we have one and only queue #0 */
-	spi_req->work_id = (knc->next_work_id ^ knc->salt) & WORK_ID_MASK;
+	spi_req->work_id = (work_id ^ knc->salt) & WORK_ID_MASK;
 	q_work->work_id = spi_req->work_id;
-	++(knc->next_work_id);
 	buf_to = spi_req->midstate;
 	buf_from = (uint32_t *)q_work->work->midstate;
 
@@ -523,6 +522,8 @@ static int64_t knc_process_response(struct thr_info *thr, struct cgpu_info *cgpu
 	if (knc->write_q <= knc->read_q)
 		num_sent += KNC_QUEUED_BUFFER_SIZE;
 
+	knc->next_work_id += rxbuf->works_accepted;
+
 	/* Actually process SPI response */
 	if (rxbuf->works_accepted) {
 		applog(LOG_DEBUG, "KnC spi: raw response %08X %08X",
@@ -798,11 +799,15 @@ static int64_t knc_scanwork(struct thr_info *thr)
 
 	while (next_read_q != knc->write_q) {
 		knc_work_from_queue_to_spi(knc, &knc->queued_fifo[next_read_q],
-					   &spi_txbuf[num]);
+					   &spi_txbuf[num], knc->next_work_id + num);
 		knc_queued_fifo_inc_idx(&next_read_q);
 		++num;
 	}
-	/* knc->read_q is advanced in knc_process_response, not here */
+	/* knc->read_q is advanced in knc_process_response, not here.
+	 * knc->next_work_id is advanced in knc_process_response as well,
+	 *   because only after SPI response we know how many works were actually
+	 *   consumed by FPGA.
+	 */
 
 	len = spi_transfer(knc->ctx, (uint8_t *)spi_txbuf,
 			   (uint8_t *)&spi_rxbuf, sizeof(spi_txbuf));