Merge "[BugFix][Feature][T106BUG-641] SPI packet loss problem, merged into ZXW patch start"
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spi-zx29.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spi-zx29.c
index d570db1..3d371ea 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spi-zx29.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spi-zx29.c
@@ -158,8 +158,6 @@
#define SPI_INTR_EN_MASK_TX_EMPTY_IE (0x1UL << 3)
#define SPI_INTR_EN_MASK_RX_THRES_IE (0x1UL << 4)
#define SPI_INTR_EN_MASK_TX_THRES_IE (0x1UL << 5)
-//yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
-#define SPI_INTR_EN_MASK_MST_EOT_IE (0x1UL << 6)
/*
* SPI Interrupt Status Register OR Interrupt Clear Register - SPI_INTR_SR_SCLR
@@ -1984,24 +1982,25 @@
return ret;
}
+/* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
/* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
-#define SPI_SLVAE_RX_BUFF_SIZE 4096
-#define SPI_SLVAE_RX_MAX_PACK_NUM 15
-#define SPI_SLVAE_RX_PACK_LEN 146
-#define SPI_SLVAE_RX_LIST_BUFF_LEN (SPI_SLVAE_RX_MAX_PACK_NUM*SPI_SLVAE_RX_PACK_LEN)
-static dma_channel_def slave_rx_conf[SPI_SLVAE_RX_MAX_PACK_NUM] = {0};
+#define SPI_SLAVE_RX_BUFF_SIZE 4096
+#define SPI_SLAVE_RX_MAX_PACK_NUM 15
+#define SPI_SLAVE_RX_PACK_LEN 146
+#define SPI_SLAVE_RX_LIST_BUFF_LEN (SPI_SLAVE_RX_MAX_PACK_NUM*SPI_SLAVE_RX_PACK_LEN)
+static dma_channel_def slave_rx_conf[SPI_SLAVE_RX_MAX_PACK_NUM] = {0};
//yu.dong@20240617 [T106BUG-641] SPI packet loss issue, increase kernel buffer and read all cached data away, no data loss.
#define SPI_MAGIC 0x55555555
static bool rxbuf_is_free_space(struct spi_device *spi)
{
if (spi->recv_pos < spi->rd_pos) {
- if ((spi->rd_pos - spi->recv_pos) > SPI_SLVAE_RX_PACK_LEN)
+ if ((spi->rd_pos - spi->recv_pos) > SPI_SLAVE_RX_PACK_LEN)
return 1;
else
return 0;
}
else {
- if ((SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos + spi->rd_pos ) > SPI_SLVAE_RX_PACK_LEN)
+ if ((SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos + spi->rd_pos ) > SPI_SLAVE_RX_PACK_LEN)
return 1;
else
return 0;
@@ -2018,26 +2017,26 @@
zx29spi = spi_master_get_devdata(spi->master);
zx29spi->spi_poll_cnt++;
- end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4);
- while((end != SPI_MAGIC) && index < SPI_SLVAE_RX_MAX_PACK_NUM) {
+ end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4);
+ while((end != SPI_MAGIC) && index < SPI_SLAVE_RX_MAX_PACK_NUM) {
if(!rxbuf_is_free_space(spi)) {
printk("rx_buff not enough space!!!!!");
zx29spi->spi_dma_cnt++;
break;
}else {
- if((spi->recv_pos + SPI_SLVAE_RX_PACK_LEN) <= SPI_SLVAE_RX_BUFF_SIZE) {
- memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN,SPI_SLVAE_RX_PACK_LEN);
+ if((spi->recv_pos + SPI_SLAVE_RX_PACK_LEN) <= SPI_SLAVE_RX_BUFF_SIZE) {
+ memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN,SPI_SLAVE_RX_PACK_LEN);
}else {
- memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN,SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos);
- memcpy(spi->rx_buf,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + (SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos),SPI_SLVAE_RX_PACK_LEN-(SPI_SLVAE_RX_BUFF_SIZE-spi->recv_pos));
+ memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN,SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos);
+ memcpy(spi->rx_buf,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + (SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos),SPI_SLAVE_RX_PACK_LEN-(SPI_SLAVE_RX_BUFF_SIZE-spi->recv_pos));
}
- *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4) = SPI_MAGIC;
- spi->recv_pos = (spi->recv_pos + SPI_SLVAE_RX_PACK_LEN)%SPI_SLVAE_RX_BUFF_SIZE;
- spi->cyc_index = (spi->cyc_index + 1)%SPI_SLVAE_RX_MAX_PACK_NUM;
+ *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4) = SPI_MAGIC;
+ spi->recv_pos = (spi->recv_pos + SPI_SLAVE_RX_PACK_LEN)%SPI_SLAVE_RX_BUFF_SIZE;
+ spi->cyc_index = (spi->cyc_index + 1)%SPI_SLAVE_RX_MAX_PACK_NUM;
zx29spi->spi_dma_cnt++;
index++;
- end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4);
+ end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4);
}
if(spi->is_rd_waiting == true && spi->recv_done == 0) {
@@ -2045,7 +2044,7 @@
spi->recv_done = 1;
}
}
- if((end != SPI_MAGIC) && index == SPI_SLVAE_RX_MAX_PACK_NUM)
+ if((end != SPI_MAGIC) && index == SPI_SLAVE_RX_MAX_PACK_NUM)
printk("cyc_buf be covered!!!!!");
return;
}
@@ -2056,7 +2055,7 @@
struct chip_data *chip = NULL;
struct dma_chan *rxchan = NULL;
struct dma_async_tx_descriptor *rxdesc;
- unsigned short transfer_len = SPI_SLVAE_RX_PACK_LEN;
+ unsigned short transfer_len = SPI_SLAVE_RX_PACK_LEN;
int i;
chip = zx29spi->cur_chip = spi->controller_state;
@@ -2079,7 +2078,7 @@
* not trigger on 2 elements this needs explicit mapping rather than
* calculation.
*/
- for(i = 0;i < SPI_SLVAE_RX_MAX_PACK_NUM;i++) {
+ for(i = 0;i < SPI_SLAVE_RX_MAX_PACK_NUM;i++) {
switch (zx29spi->rx_lev_trig) {
case SPI_RX_1_OR_MORE_ELEM:
slave_rx_conf[i].dma_control.src_burst_len = DMA_BURST_LEN_1;
@@ -2144,7 +2143,7 @@
/* Submit and fire RX and TX with TX last so we're ready to read! */
if (spi->rx_dma) {
- rxdesc = rxchan->device->device_prep_dma_cyclic(rxchan,NULL,SPI_SLVAE_RX_MAX_PACK_NUM * SPI_SLVAE_RX_PACK_LEN, SPI_SLVAE_RX_PACK_LEN,0,0);
+ rxdesc = rxchan->device->device_prep_dma_cyclic(rxchan,NULL,SPI_SLAVE_RX_MAX_PACK_NUM * SPI_SLAVE_RX_PACK_LEN, SPI_SLAVE_RX_PACK_LEN,0,0);
if (!rxdesc) {
printk(KERN_INFO "!!ERROR DESC !!![%s][%d]\n",__func__,__LINE__);
dmaengine_terminate_all(rxchan);
@@ -2170,14 +2169,13 @@
printk("zx29_slave_rd_start...\r\n");
zx29spi = spi_master_get_devdata(spi->master);
- dev = &zx29spi->pdev->dev;
if (!zx29spi)
return -EINVAL;
-
+ dev = &zx29spi->pdev->dev;
spi->cyc_index = 0;
spi->rd_pos = spi->recv_pos = 0;
- spi->cyc_buf = dma_alloc_coherent(dev, SPI_SLVAE_RX_BUFF_SIZE, &spi->rx_dma, GFP_KERNEL);
+ spi->cyc_buf = dma_alloc_coherent(dev, SPI_SLAVE_RX_BUFF_SIZE, &spi->rx_dma, GFP_KERNEL);
if (dma_mapping_error(dev, spi->rx_dma)) {
dev_err(dev, "dma_map_single spi rx failed\n");
return -ENOMEM;
@@ -2203,10 +2201,9 @@
struct dma_chan *rxchan = NULL;
zx29spi = spi_master_get_devdata(spi->master);
- dev = &zx29spi->pdev->dev;
if (!zx29spi)
return -EINVAL;
-
+ dev = &zx29spi->pdev->dev;
chip = zx29spi->cur_chip= spi->controller_state;
writel(chip->fifo_ctrl, (SPI_FIFO_CTRL_OFFSET+zx29spi->virtbase));
rxchan = zx29spi->dma_rx_channel;
@@ -2217,7 +2214,7 @@
}
if(spi->cyc_buf != NULL && spi->rx_dma) {
- dma_free_coherent(dev, SPI_SLVAE_RX_BUFF_SIZE, spi->cyc_buf, spi->rx_dma);
+ dma_free_coherent(dev, SPI_SLAVE_RX_BUFF_SIZE, spi->cyc_buf, spi->rx_dma);
spi->cyc_buf = NULL;
}
@@ -2230,6 +2227,7 @@
return status;
}
/* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+/* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end*/
static int zx29_prepare_transfer_hardware(struct spi_master *master)
{
@@ -2611,7 +2609,10 @@
ktime_t k_time_start = 0;
ktime_t k_time_end = 0;
ktime_t diff_ns = 0;
- /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+ /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+ if(false == zx29spi->master->slave)
+ pm_stay_awake(&zx29spi->pdev->dev);
regval = readl((SPI_COM_CTRL_OFFSET+zx29spi->virtbase)) & (~SPI_COM_CTRL_MASK_SSPE);
writel(regval, (SPI_COM_CTRL_OFFSET+zx29spi->virtbase));
@@ -2635,7 +2636,10 @@
if(diff_ns >= 10000000) {
dev_info(&zx29spi->pdev->dev, " zx29_setup_to_regs failed! diff_ns=%lld \n",diff_ns);
}
-
+
+ if(false == zx29spi->master->slave)
+ pm_relax(&zx29spi->pdev->dev);
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
}
/**
* zx29_setup - setup function registered to SPI master framework
@@ -2821,7 +2825,10 @@
zx29_setup_to_regs(chip,zx29spi);
}
- //yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
+ if(zx29spi->mode == ZX29_SSP_MASTER_TYPE) {
+ if(spi->setup_immediately == 1)
+ zx29_setup_to_regs(chip,zx29spi);
+ }
return status;
err_config_params:
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spidev.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spidev.c
index 1522a21..2a7cdbc 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spidev.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/spi/spidev.c
@@ -217,48 +217,30 @@
return -EMSGSIZE;
spidev = filp->private_data;
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+ if(spidev->spi->master->slave) {
+ #ifdef SPI_SLAVE_FOR_YK
+ size_t total = 0;
+ if (spidev->spi->rd_pos == spidev->spi->recv_pos) {
-
- #ifdef SPI_SLAVE_FOR_YK
- size_t total = 0;
-
- if (spidev->spi->rd_pos == spidev->spi->recv_pos) {
-
- status = 0;
- spidev->spi->is_rd_waiting = true;
- if(0 != wait_event_freezable(spidev->spi->rd_wait, spidev->spi->recv_done)) {
- if(spidev->spi->controller->spi_slave_rd_stop)
- spidev->spi->controller->spi_slave_rd_stop(spidev->spi);
- spidev->spi->is_rd_waiting = false;
- return status;
- }else {
- spidev->spi->recv_done = false;
- spidev->spi->is_rd_waiting = false;
+ status = 0;
+ spidev->spi->is_rd_waiting = true;
+ if(0 != wait_event_freezable(spidev->spi->rd_wait, spidev->spi->recv_done)) {
+ if(spidev->spi->controller->spi_slave_rd_stop)
+ spidev->spi->controller->spi_slave_rd_stop(spidev->spi);
+ spidev->spi->is_rd_waiting = false;
+ return status;
+ }else {
+ spidev->spi->recv_done = false;
+ spidev->spi->is_rd_waiting = false;
+ }
}
- }
- mutex_lock(&spidev->buf_lock);
- if(spidev->spi->rd_pos < spidev->spi->recv_pos) {
+ mutex_lock(&spidev->buf_lock);
+ if(spidev->spi->rd_pos < spidev->spi->recv_pos) {
- total = spidev->spi->recv_pos - spidev->spi->rd_pos;
- status = (total > count) ? count : total;
-
- missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
- if (missing == status) {
- status = -EFAULT;
- }
- else {
- status = status - missing;
- spidev->spi->rd_pos += status;
- }
-
- }else if(spidev->spi->rd_pos > spidev->spi->recv_pos) {
-
- total = bufsiz - (spidev->spi->rd_pos - spidev->spi->recv_pos);
- status = (total > count) ? count : total;
-
- if((spidev->spi->rd_pos + status) <= bufsiz) {
-
+ total = spidev->spi->recv_pos - spidev->spi->rd_pos;
+ status = (total > count) ? count : total;
missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
if (missing == status) {
status = -EFAULT;
@@ -266,48 +248,81 @@
else {
status = status - missing;
spidev->spi->rd_pos += status;
- spidev->spi->rd_pos = spidev->spi->rd_pos%bufsiz;
- }
- }else {
-
- unsigned long first,rest;
-
- first = bufsiz - spidev->spi->rd_pos;
- missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, first);
- if (missing == first) {
- status = -EFAULT;
- } else {
- status = status - missing;
}
- rest = status-first;
- missing = copy_to_user(buf+first, spidev->rx_buffer, rest);
- if (missing == rest) {
- status = -EFAULT;
- } else {
- status = status - missing;
+ }else if(spidev->spi->rd_pos > spidev->spi->recv_pos) {
+
+ total = bufsiz - (spidev->spi->rd_pos - spidev->spi->recv_pos);
+ status = (total > count) ? count : total;
+
+ if((spidev->spi->rd_pos + status) <= bufsiz) {
+
+ missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
+ if (missing == status) {
+ status = -EFAULT;
+ }
+ else {
+ status = status - missing;
+ spidev->spi->rd_pos += status;
+ spidev->spi->rd_pos = spidev->spi->rd_pos%bufsiz;
+ }
+ }else {
+
+ unsigned long first,rest;
+
+ first = bufsiz - spidev->spi->rd_pos;
+ missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, first);
+ if (missing == first) {
+ status = -EFAULT;
+ } else {
+ status = status - missing;
+ }
+
+ rest = status-first;
+ missing = copy_to_user(buf+first, spidev->rx_buffer, rest);
+ if (missing == rest) {
+ status = -EFAULT;
+ } else {
+ status = status - missing;
+ }
+ spidev->spi->rd_pos = rest;
}
- spidev->spi->rd_pos = rest;
}
- }
- #else
- mutex_lock(&spidev->buf_lock);
- if(spidev->rd_from_rx_buffer)
- status = count;
- else
- status = spidev_sync_read(spidev, count);
-
- if (status > 0) {
-
- missing = copy_to_user(buf, spidev->rx_buffer, status);
- if (missing == status)
- status = -EFAULT;
+ #else
+ mutex_lock(&spidev->buf_lock);
+ if(spidev->rd_from_rx_buffer)
+ status = count;
else
- status = status - missing;
- }
- #endif
- mutex_unlock(&spidev->buf_lock);
+ status = spidev_sync_read(spidev, count);
+ if (status > 0) {
+
+ missing = copy_to_user(buf, spidev->rx_buffer, status);
+ if (missing == status)
+ status = -EFAULT;
+ else
+ status = status - missing;
+ }
+ #endif
+ mutex_unlock(&spidev->buf_lock);
+ }else {
+ mutex_lock(&spidev->buf_lock);
+
+ if(spidev->rd_from_rx_buffer)
+ status = count;
+ else
+ status = spidev_sync_read(spidev, count);
+
+ if(status > 0) {
+ missing = copy_to_user(buf, spidev->rx_buffer, status);
+ if (missing == status)
+ status = -EFAULT;
+ else
+ status = status - missing;
+ }
+ mutex_unlock(&spidev->buf_lock);
+ }
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
return status;
}
/* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end*/
@@ -783,15 +798,19 @@
}
}
- /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
- #ifdef SPI_SLAVE_FOR_YK
- if(spidev->rx_buffer) {
- spidev->spi->rx_buf = spidev->rx_buffer;
- if(spidev->spi->controller->spi_slave_rd_start)
- spidev->spi->controller->spi_slave_rd_start(spidev->spi);
- }
- #endif
- /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+ /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+ if(spidev->spi->master->slave) {
+ #ifdef SPI_SLAVE_FOR_YK
+ if(spidev->rx_buffer) {
+ spidev->spi->rx_buf = spidev->rx_buffer;
+ if(spidev->spi->controller->spi_slave_rd_start)
+ spidev->spi->controller->spi_slave_rd_start(spidev->spi);
+ }
+ #endif
+ }
+ /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
spidev->users++;
filp->private_data = spidev;
stream_open(inode, filp);
@@ -838,14 +857,18 @@
spi = spi_dev_get(spidev->spi);
spin_unlock_irq(&spidev->spi_lock);
- /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
- #ifdef SPI_SLAVE_FOR_YK
- if(spidev->rx_buffer) {
- if(spi->controller->spi_slave_rd_stop)
- spi->controller->spi_slave_rd_stop(spi);
- }
- #endif
- /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+ /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+ if(spidev->spi->master->slave) {
+ #ifdef SPI_SLAVE_FOR_YK
+ if(spidev->rx_buffer) {
+ if(spi->controller->spi_slave_rd_stop)
+ spi->controller->spi_slave_rd_stop(spi);
+ }
+ #endif
+ }
+ /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+ /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end*/
if(spi && spi->master->slave)
pm_relax(&spi->dev);
kfree(spidev->tx_buffer);
@@ -2257,7 +2280,14 @@
dev_info(&spi->dev,"trans_gap_num = 0x%x",val);
}
- // yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
+ if (device_property_read_u32(&spi->dev, "setup-immediately",&val)) {
+ spi->setup_immediately = 0;
+ dev_err(&spi->dev,"setup-immediately get failed");
+ }
+ else {
+ spi->setup_immediately = val;
+ dev_info(&spi->dev,"setup-immediately = 0x%x",val);
+ }
/* If we can allocate a minor number, hook up this device.
* Reusing minors is fine so long as udev or mdev is working.
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/spi/spi.h b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/spi/spi.h
index 569ba92..6135a82 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/spi/spi.h
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/spi/spi.h
@@ -210,7 +210,8 @@
u8 trans_gaped;
u8 trans_gap_num;
/* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
- u32 rd_pos;
+ u8 setup_immediately;
+ u32 rd_pos;
u32 recv_pos;
u8 * rx_buf;
u8 * cyc_buf;