BigW Consortium Gitlab

Commit d1130803 by David Clark

Merge branch 'master' of ssh://github.com/mangOH/mangOH

parents 852d9948 093b57b0
Subproject commit 210805ba20d4d85867d9a9f56fd9762c945aee62 Subproject commit 78a864d53e70fd53ad29744688032e9913db102f
Subproject commit 7c01aa8a0abf11ab8112bc0ebc85bb79776c45c6 Subproject commit 103c5a071d7ad191b3bd7faa84de4a72aeeec700
...@@ -17,10 +17,8 @@ ...@@ -17,10 +17,8 @@
#ifndef _MT7697_I_H_ #ifndef _MT7697_I_H_
#define _MT7697_I_H_ #define _MT7697_I_H_
#define LEN32_ALIGNED(x) (((x) / sizeof(u32) + \ #define LEN_TO_WORD(x) ((x) / sizeof(u32) + ((x) % sizeof(u32) ? 1 : 0))
((x) % sizeof(u32) ? 1:0)) * sizeof(u32)) #define LEN32_ALIGNED(x) (LEN_TO_WORD(x) * sizeof(u32))
#define LEN_TO_WORD(x) ((x) / sizeof(u32) + \
((x) % sizeof(u32) ? 1:0))
enum mt7697_cmd_grp { enum mt7697_cmd_grp {
MT7697_CMD_GRP_QUEUE = 0, MT7697_CMD_GRP_QUEUE = 0,
......
...@@ -29,49 +29,49 @@ static int mt7697q_irq_run(struct mt7697q_info *qinfo) ...@@ -29,49 +29,49 @@ static int mt7697q_irq_run(struct mt7697q_info *qinfo)
u8 s2m_mbox; u8 s2m_mbox;
ret = mt7697q_get_s2m_mbx(qinfo, &s2m_mbox); ret = mt7697q_get_s2m_mbx(qinfo, &s2m_mbox);
if (ret < 0) { if (ret < 0) {
dev_err(qinfo->dev, dev_err(qinfo->dev,
"%s(): mt7697q_get_s2m_mbx() failed(%d)\n", "%s(): mt7697q_get_s2m_mbx() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
if (s2m_mbox) { if (s2m_mbox) {
if (!queue_delayed_work(qinfo->irq_workq, if (!queue_delayed_work(qinfo->irq_workq,
&qinfo->irq_delayed_work, usecs_to_jiffies(10))) { &qinfo->irq_delayed_work, usecs_to_jiffies(10))) {
dev_err(qinfo->dev, dev_err(qinfo->dev,
"%s(): queue_delayed_work() failed\n", "%s(): queue_delayed_work() failed\n",
__func__); __func__);
ret = -EINVAL; ret = -EINVAL;
} }
} } else {
else
enable_irq(qinfo->irq); enable_irq(qinfo->irq);
}
for (ch = 0; ch < MT7697_NUM_QUEUES; ch++) { for (ch = 0; ch < MT7697_NUM_QUEUES; ch++) {
struct mt7697q_spec *qs = &qinfo->queues[ch]; struct mt7697q_spec *qs = &qinfo->queues[ch];
u32 in_use = mt7697q_flags_get_in_use(qs->data.flags); u32 in_use = mt7697q_flags_get_in_use(qs->data.flags);
u32 dir = mt7697q_flags_get_dir(qs->data.flags); u32 dir = mt7697q_flags_get_dir(qs->data.flags);
if (in_use && if (in_use &&
(s2m_mbox & (0x01 << ch))) { (s2m_mbox & (0x01 << ch))) {
if (dir == MT7697_QUEUE_DIR_S2M) { if (dir == MT7697_QUEUE_DIR_S2M) {
ret = mt7697q_proc_data(qs); ret = mt7697q_proc_data(qs);
if (ret < 0) { if (ret < 0) {
dev_err(qinfo->dev, dev_err(qinfo->dev,
"%s(): mt7697q_proc_data() failed(%d)\n", "%s(): mt7697q_proc_data() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
} } else if (mt7697q_blocked_writer(qs)) {
else if (mt7697q_blocked_writer(qs)) { WARN_ON(!qs->notify_tx_fcn);
WARN_ON(!qs->notify_tx_fcn); ret = qs->notify_tx_fcn(qs->priv,
ret = qs->notify_tx_fcn(qs->priv, mt7697q_get_free_words(qs)); mt7697q_get_free_words(qs));
if (ret < 0) { if (ret < 0) {
dev_err(qs->qinfo->dev, dev_err(qs->qinfo->dev,
"%s(): notify_tx_fcn() failed(%d)\n", "%s(): notify_tx_fcn() failed(%d)\n",
__func__, ret); __func__, ret);
} }
} }
} }
} }
...@@ -82,16 +82,16 @@ cleanup: ...@@ -82,16 +82,16 @@ cleanup:
void mt7697q_irq_delayed_work(struct work_struct *irq_delayed_work) void mt7697q_irq_delayed_work(struct work_struct *irq_delayed_work)
{ {
struct mt7697q_info *qinfo = container_of(irq_delayed_work, struct mt7697q_info *qinfo = container_of(irq_delayed_work,
struct mt7697q_info, irq_delayed_work.work); struct mt7697q_info, irq_delayed_work.work);
int ret; int ret;
dev_dbg(qinfo->dev, "%s(): process work\n", __func__); dev_dbg(qinfo->dev, "%s(): process work\n", __func__);
ret = mt7697q_irq_run(qinfo); ret = mt7697q_irq_run(qinfo);
if (ret < 0) { if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697q_irq_run() failed(%d)\n", dev_err(qinfo->dev, "%s(): mt7697q_irq_run() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
cleanup: cleanup:
...@@ -100,17 +100,17 @@ cleanup: ...@@ -100,17 +100,17 @@ cleanup:
void mt7697q_irq_work(struct work_struct *irq_work) void mt7697q_irq_work(struct work_struct *irq_work)
{ {
struct mt7697q_info *qinfo = container_of(irq_work, struct mt7697q_info *qinfo = container_of(irq_work,
struct mt7697q_info, irq_work); struct mt7697q_info, irq_work);
int ret; int ret;
dev_dbg(qinfo->dev, "%s(): process work\n", __func__); dev_dbg(qinfo->dev, "%s(): process work\n", __func__);
ret = mt7697q_irq_run(qinfo); ret = mt7697q_irq_run(qinfo);
if (ret < 0) { if (ret < 0) {
dev_err(qinfo->dev, dev_err(qinfo->dev,
"%s(): mt7697q_irq_run() failed(%d)\n", "%s(): mt7697q_irq_run() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
cleanup: cleanup:
...@@ -121,10 +121,10 @@ irqreturn_t mt7697q_isr(int irq, void *arg) ...@@ -121,10 +121,10 @@ irqreturn_t mt7697q_isr(int irq, void *arg)
{ {
struct mt7697q_info *qinfo = (struct mt7697q_info*)arg; struct mt7697q_info *qinfo = (struct mt7697q_info*)arg;
disable_irq_nosync(qinfo->irq); disable_irq_nosync(qinfo->irq);
if (!queue_work(qinfo->irq_workq, &qinfo->irq_work)) { if (!queue_work(qinfo->irq_workq, &qinfo->irq_work)) {
dev_err(qinfo->dev, "%s(): queue_work() failed\n", __func__); dev_err(qinfo->dev, "%s(): queue_work() failed\n", __func__);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -84,8 +84,8 @@ ...@@ -84,8 +84,8 @@
struct mt7697q_info; struct mt7697q_info;
int mt7697io_wr_m2s_mbx(struct mt7697q_info*, u8); int mt7697io_wr_m2s_mbx(struct mt7697q_info*, u8);
int mt7697io_rd_s2m_mbx(struct mt7697q_info*); int mt7697io_rd_s2m_mbx(struct mt7697q_info*, u8*);
int mt7697io_clr_s2m_mbx(struct mt7697q_info*); int mt7697io_clr_s2m_mbx(struct mt7697q_info*, u8);
int mt7697io_wr(struct mt7697q_info*, u32, const u32*, size_t); int mt7697io_wr(struct mt7697q_info*, u32, const u32*, size_t);
int mt7697io_rd(struct mt7697q_info*, u32, u32*, size_t); int mt7697io_rd(struct mt7697q_info*, u32, u32*, size_t);
......
...@@ -35,43 +35,39 @@ ...@@ -35,43 +35,39 @@
#define MT7697_QUEUE_DEBUG_DUMP_LIMIT 1024 #define MT7697_QUEUE_DEBUG_DUMP_LIMIT 1024
struct mt7697q_data { struct mt7697q_data {
u32 flags; u32 flags;
u32 base_addr; u32 base_addr;
u16 rd_offset; u16 rd_offset;
u16 reserved1; u16 reserved1;
u16 wr_offset; u16 wr_offset;
u16 reserved2; u16 reserved2;
}; };
struct mt7697q_spec { struct mt7697q_spec {
struct mt7697q_data data; struct mt7697q_data data;
struct mt7697q_info *qinfo; struct mt7697q_info *qinfo;
void *priv; void *priv;
notify_tx_hndlr notify_tx_fcn; notify_tx_hndlr notify_tx_fcn;
rx_hndlr rx_fcn; rx_hndlr rx_fcn;
u8 ch; u8 ch;
}; };
struct mt7697q_info { struct mt7697q_info {
struct mt7697q_spec queues[MT7697_NUM_QUEUES]; struct mt7697q_spec queues[MT7697_NUM_QUEUES];
struct mt7697_rsp_hdr rsp; struct mt7697_rsp_hdr rsp;
u8 txBuffer[sizeof(u32)];
u8 rxBuffer[sizeof(u32)]; struct device *dev;
void *hw_priv;
struct device *dev; const struct mt7697spi_hw_ops *hw_ops;
void *hw_priv;
const struct mt7697spi_hw_ops *hw_ops;
struct mutex mutex; struct mutex mutex;
struct workqueue_struct *irq_workq; struct workqueue_struct *irq_workq;
struct work_struct irq_work; struct work_struct irq_work;
struct delayed_work irq_delayed_work; struct delayed_work irq_delayed_work;
atomic_t blocked_writer; atomic_t blocked_writer;
int gpio_pin; int gpio_pin;
int irq; int irq;
u8 s2m_mbox;
bool slave_busy;
}; };
void mt7697q_irq_delayed_work(struct work_struct*); void mt7697q_irq_delayed_work(struct work_struct*);
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
#include "mt7697_i.h" #include "mt7697_i.h"
#define mt7697_queue_init_rsp mt7697_rsp_hdr #define mt7697_queue_init_rsp mt7697_rsp_hdr
#define mt7697_queue_reset_rsp mt7697_rsp_hdr #define mt7697_queue_reset_rsp mt7697_rsp_hdr
enum mt7697q_dir enum mt7697q_dir
{ {
MT7697_QUEUE_DIR_M2S = 0, MT7697_QUEUE_DIR_M2S = 0,
MT7697_QUEUE_DIR_S2M, MT7697_QUEUE_DIR_S2M,
}; };
enum mt7697q_cmd_types { enum mt7697q_cmd_types {
...@@ -37,21 +37,21 @@ enum mt7697q_cmd_types { ...@@ -37,21 +37,21 @@ enum mt7697q_cmd_types {
}; };
struct mt7697_queue_init_req { struct mt7697_queue_init_req {
struct mt7697_cmd_hdr cmd; struct mt7697_cmd_hdr cmd;
__be32 m2s_ch; __be32 m2s_ch;
__be32 s2m_ch; __be32 s2m_ch;
} __attribute__((packed, aligned(4))); } __attribute__((packed, aligned(4)));
struct mt7697_queue_unused_req { struct mt7697_queue_unused_req {
struct mt7697_cmd_hdr cmd; struct mt7697_cmd_hdr cmd;
__be32 m2s_ch; __be32 m2s_ch;
__be32 s2m_ch; __be32 s2m_ch;
} __attribute__((packed, aligned(4))); } __attribute__((packed, aligned(4)));
struct mt7697_queue_reset_req { struct mt7697_queue_reset_req {
struct mt7697_cmd_hdr cmd; struct mt7697_cmd_hdr cmd;
__be32 m2s_ch; __be32 m2s_ch;
__be32 s2m_ch; __be32 s2m_ch;
} __attribute__((packed, aligned(4))); } __attribute__((packed, aligned(4)));
u32 mt7697q_flags_get_in_use(u32); u32 mt7697q_flags_get_in_use(u32);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "spi.h" #include "spi.h"
static int mt7697spi_write_then_read(struct spi_device *spi, const void *txbuf, static int mt7697spi_write_then_read(struct spi_device *spi, const void *txbuf,
void *rxbuf, unsigned len) void *rxbuf, unsigned len)
{ {
struct spi_transfer transfer = { struct spi_transfer transfer = {
.tx_buf = txbuf, .tx_buf = txbuf,
...@@ -85,7 +85,7 @@ static int __init mt7697spi_init(void) ...@@ -85,7 +85,7 @@ static int __init mt7697spi_init(void)
while (!master && (bus_num >= 0)) { while (!master && (bus_num >= 0)) {
master = spi_busnum_to_master(bus_num); master = spi_busnum_to_master(bus_num);
if (!master) if (!master)
bus_num--; bus_num--;
} }
...@@ -97,88 +97,87 @@ static int __init mt7697spi_init(void) ...@@ -97,88 +97,87 @@ static int __init mt7697spi_init(void)
ret = cp2130_update_ch_config(master, MT7697_SPI_CONFIG); ret = cp2130_update_ch_config(master, MT7697_SPI_CONFIG);
if (ret < 0) { if (ret < 0) {
dev_err(&master->dev, dev_err(&master->dev,
"%s(): cp2130_update_ch_config() failed(%d)\n", "%s(): cp2130_update_ch_config() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), MT7697_SPI_CS); snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev),
MT7697_SPI_CS);
dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str); dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str);
dev = bus_find_device_by_name(&spi_bus_type, NULL, str); dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
if (!dev) { if (!dev) {
dev_err(&master->dev, dev_err(&master->dev,
"%s(): bus_find_device_by_name('%s') failed\n", "%s(): bus_find_device_by_name('%s') failed\n",
__func__, str); __func__, str);
ret = -EINVAL; ret = -EINVAL;
goto cleanup; goto cleanup;
} }
spi = container_of(dev, struct spi_device, dev); spi = to_spi_device(dev);
if (!spi) { if (!spi) {
dev_err(&master->dev, "%s(): get SPI device failed\n", dev_err(&master->dev, "%s(): get SPI device failed\n",
__func__); __func__);
ret = -EINVAL; ret = -EINVAL;
goto cleanup; goto cleanup;
} }
dev_info(&master->dev, "%s(): dev('%s') mode(%d) max speed(%d) " dev_info(&master->dev, "%s(): dev('%s') mode(%d) max speed(%d) "
"CS(%d) bits/word(%d)\n", "CS(%d) bits/word(%d)\n",
__func__, spi->modalias, spi->mode, spi->max_speed_hz, __func__, spi->modalias, spi->mode, spi->max_speed_hz,
spi->chip_select, spi->bits_per_word); spi->chip_select, spi->bits_per_word);
qinfo = kzalloc(sizeof(struct mt7697q_info), GFP_KERNEL); qinfo = kzalloc(sizeof(struct mt7697q_info), GFP_KERNEL);
if (!qinfo) { if (!qinfo) {
dev_err(&master->dev, "%s(): create queue info failed\n", dev_err(&master->dev, "%s(): create queue info failed\n",
__func__); __func__);
ret = -ENOMEM; ret = -ENOMEM;
goto cleanup; goto cleanup;
} }
memset(qinfo, 0, sizeof(struct mt7697q_info));
qinfo->dev = &spi->dev; qinfo->dev = &spi->dev;
qinfo->hw_priv = spi; qinfo->hw_priv = spi;
qinfo->hw_ops = &hw_ops; qinfo->hw_ops = &hw_ops;
mutex_init(&qinfo->mutex); mutex_init(&qinfo->mutex);
INIT_DELAYED_WORK(&qinfo->irq_delayed_work, mt7697q_irq_delayed_work); INIT_DELAYED_WORK(&qinfo->irq_delayed_work, mt7697q_irq_delayed_work);
INIT_WORK(&qinfo->irq_work, mt7697q_irq_work); INIT_WORK(&qinfo->irq_work, mt7697q_irq_work);
qinfo->irq_workq = alloc_workqueue(DRVNAME"wq", qinfo->irq_workq = alloc_workqueue(DRVNAME"wq",
WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
if (!qinfo->irq_workq) { if (!qinfo->irq_workq) {
dev_err(qinfo->dev, "%s(): alloc_workqueue() failed\n", dev_err(qinfo->dev, "%s(): alloc_workqueue() failed\n",
__func__); __func__);
ret = -ENOMEM; ret = -ENOMEM;
goto cleanup; goto cleanup;
} }
qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN; qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN;
ret = gpio_request(qinfo->gpio_pin, MT7697_SPI_GPIO_IRQ_NAME); ret = gpio_request(qinfo->gpio_pin, MT7697_SPI_GPIO_IRQ_NAME);
if (ret < 0) { if (ret < 0) {
if (ret != -EBUSY) { if (ret != -EBUSY) {
dev_err(qinfo->dev, "%s(): gpio_request() failed(%d)", dev_err(qinfo->dev, "%s(): gpio_request() failed(%d)",
__func__, ret); __func__, ret);
goto failed_workqueue; goto failed_workqueue;
} }
qinfo->irq = gpio_to_irq(qinfo->gpio_pin); qinfo->irq = gpio_to_irq(qinfo->gpio_pin);
qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN_INVALID; qinfo->gpio_pin = MT7697_SPI_INTR_GPIO_PIN_INVALID;
} } else {
else {
gpio_direction_input(qinfo->gpio_pin); gpio_direction_input(qinfo->gpio_pin);
qinfo->irq = gpio_to_irq(qinfo->gpio_pin); qinfo->irq = gpio_to_irq(qinfo->gpio_pin);
} }
dev_info(qinfo->dev, "%s(): request irq(%d)\n", __func__, qinfo->irq); dev_info(qinfo->dev, "%s(): request irq(%d)\n", __func__, qinfo->irq);
ret = request_irq(qinfo->irq, mt7697q_isr, 0, DRVNAME, qinfo); ret = request_irq(qinfo->irq, mt7697q_isr, 0, DRVNAME, qinfo);
if (ret < 0) { if (ret < 0) {
dev_err(qinfo->dev, "%s(): request_irq() failed(%d)", dev_err(qinfo->dev, "%s(): request_irq() failed(%d)",
__func__, ret); __func__, ret);
goto failed_gpio_req; goto failed_gpio_req;
} }
irq_set_irq_type(qinfo->irq, IRQ_TYPE_EDGE_BOTH); irq_set_irq_type(qinfo->irq, IRQ_TYPE_EDGE_BOTH);
...@@ -187,12 +186,12 @@ static int __init mt7697spi_init(void) ...@@ -187,12 +186,12 @@ static int __init mt7697spi_init(void)
dev_info(qinfo->dev, "%s(): '%s' initialized\n", __func__, DRVNAME); dev_info(qinfo->dev, "%s(): '%s' initialized\n", __func__, DRVNAME);
return 0; return 0;
failed_workqueue:
destroy_workqueue(qinfo->irq_workq);
failed_gpio_req: failed_gpio_req:
if (qinfo->gpio_pin > 0) gpio_free(qinfo->gpio_pin); if (qinfo->gpio_pin > 0) gpio_free(qinfo->gpio_pin);
failed_workqueue:
destroy_workqueue(qinfo->irq_workq);
cleanup: cleanup:
if (qinfo) kfree(qinfo); if (qinfo) kfree(qinfo);
return ret; return ret;
...@@ -218,27 +217,28 @@ static void __exit mt7697spi_exit(void) ...@@ -218,27 +217,28 @@ static void __exit mt7697spi_exit(void)
goto cleanup; goto cleanup;
} }
snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), MT7697_SPI_CS); snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev),
MT7697_SPI_CS);
dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str); dev_info(&master->dev, "%s(): find SPI device('%s')\n", __func__, str);
dev = bus_find_device_by_name(&spi_bus_type, NULL, str); dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
if (!dev) { if (!dev) {
dev_err(&master->dev, dev_err(&master->dev,
"%s(): '%s' bus_find_device_by_name() failed\n", "%s(): '%s' bus_find_device_by_name() failed\n",
__func__, str); __func__, str);
goto cleanup; goto cleanup;
} }
spi = container_of(dev, struct spi_device, dev); spi = to_spi_device(dev);
if (!spi) { if (!spi) {
dev_err(dev, "%s(): get SPI device failed\n", dev_err(dev, "%s(): get SPI device failed\n",
__func__); __func__);
goto cleanup; goto cleanup;
} }
qinfo = spi_get_drvdata(spi); qinfo = spi_get_drvdata(spi);
if (!qinfo) { if (!qinfo) {
dev_err(dev, "%s(): SPI device no queue info\n", dev_err(dev, "%s(): SPI device no queue info\n",
__func__); __func__);
goto cleanup; goto cleanup;
} }
...@@ -259,6 +259,6 @@ cleanup: ...@@ -259,6 +259,6 @@ cleanup:
module_init(mt7697spi_init); module_init(mt7697spi_init);
module_exit(mt7697spi_exit); module_exit(mt7697spi_exit);
MODULE_AUTHOR( "Sierra Wireless Corporation" ); MODULE_AUTHOR("Sierra Wireless Corporation");
MODULE_LICENSE( "GPL" ); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION( "MediaTek7697 SPI master" ); MODULE_DESCRIPTION("MediaTek7697 SPI master");
...@@ -22,12 +22,12 @@ ...@@ -22,12 +22,12 @@
#include "mt7697_i.h" #include "mt7697_i.h"
#include "uart_i.h" #include "uart_i.h"
#define MT7697_UART_DRVNAME "mt7697serial" #define MT7697_UART_DRVNAME "mt7697serial"
#define MT7697_UART_DEVICE "/dev/ttyHS0" #define MT7697_UART_DEVICE "/dev/ttyHS0"
#define MT7697_UART_INVALID_FD NULL #define MT7697_UART_INVALID_FD NULL
#define mt7697_uart_shutdown_req mt7697_cmd_hdr #define mt7697_uart_shutdown_req mt7697_cmd_hdr
#define mt7697_uart_shutdown_rsp mt7697_rsp_hdr #define mt7697_uart_shutdown_rsp mt7697_rsp_hdr
enum mt7697_uart_cmd_types { enum mt7697_uart_cmd_types {
MT7697_CMD_UART_SHUTDOWN_REQ = 0, MT7697_CMD_UART_SHUTDOWN_REQ = 0,
...@@ -35,20 +35,20 @@ enum mt7697_uart_cmd_types { ...@@ -35,20 +35,20 @@ enum mt7697_uart_cmd_types {
}; };
struct mt7697_uart_info { struct mt7697_uart_info {
struct platform_device *pdev; struct platform_device *pdev;
struct device *dev; struct device *dev;
char* dev_file; char *dev_file;
struct file *fd_hndl; struct file *fd_hndl;
struct mutex mutex; struct mutex mutex;
struct work_struct rx_work; struct work_struct rx_work;
struct mt7697_rsp_hdr rsp; struct mt7697_rsp_hdr rsp;
rx_hndlr rx_fcn; rx_hndlr rx_fcn;
void *rx_hndl; void *rx_hndl;
wait_queue_head_t close_wq; wait_queue_head_t close_wq;
atomic_t close; atomic_t close;
}; };
#endif #endif
...@@ -66,19 +66,19 @@ enum mt7697_sme_state { ...@@ -66,19 +66,19 @@ enum mt7697_sme_state {
}; };
enum mt7697_vif_state { enum mt7697_vif_state {
CONNECTED, CONNECTED,
CONNECT_PEND, CONNECT_PEND,
WMM_ENABLED, WMM_ENABLED,
NETQ_STOPPED, NETQ_STOPPED,
DTIM_EXPIRED, DTIM_EXPIRED,
CLEAR_BSSFILTER_ON_BEACON, CLEAR_BSSFILTER_ON_BEACON,
DTIM_PERIOD_AVAIL, DTIM_PERIOD_AVAIL,
WLAN_ENABLED, WLAN_ENABLED,
STATS_UPDATE_PEND, STATS_UPDATE_PEND,
HOST_SLEEP_MODE_CMD_PROCESSED, HOST_SLEEP_MODE_CMD_PROCESSED,
NETDEV_MCAST_ALL_ON, NETDEV_MCAST_ALL_ON,
NETDEV_MCAST_ALL_OFF, NETDEV_MCAST_ALL_OFF,
SCHED_SCANNING, SCHED_SCANNING,
}; };
struct mt7697_tx_pkt { struct mt7697_tx_pkt {
...@@ -88,9 +88,9 @@ struct mt7697_tx_pkt { ...@@ -88,9 +88,9 @@ struct mt7697_tx_pkt {
struct mt7697_cfg80211_info { struct mt7697_cfg80211_info {
struct device *dev; struct device *dev;
struct wiphy *wiphy; struct wiphy *wiphy;
struct semaphore sem; struct semaphore sem;
struct platform_device *hif_priv; struct platform_device *hif_priv;
const struct mt7697_if_ops *hif_ops; const struct mt7697_if_ops *hif_ops;
...@@ -110,7 +110,7 @@ struct mt7697_cfg80211_info { ...@@ -110,7 +110,7 @@ struct mt7697_cfg80211_info {
u8 rx_data[LEN32_ALIGNED(IEEE80211_MAX_FRAME_LEN)]; u8 rx_data[LEN32_ALIGNED(IEEE80211_MAX_FRAME_LEN)];
u8 probe_data[LEN32_ALIGNED(IEEE80211_MAX_DATA_LEN)]; u8 probe_data[LEN32_ALIGNED(IEEE80211_MAX_DATA_LEN)];
enum mt7697_port_type port_type; enum mt7697_port_type port_type;
enum mt7697_wifi_phy_mode_t wireless_mode; enum mt7697_wifi_phy_mode_t wireless_mode;
enum mt7697_wifi_phy_mode_t hw_wireless_mode; enum mt7697_wifi_phy_mode_t hw_wireless_mode;
...@@ -163,7 +163,7 @@ struct mt7697_vif { ...@@ -163,7 +163,7 @@ struct mt7697_vif {
u8 req_bssid[ETH_ALEN]; u8 req_bssid[ETH_ALEN];
u8 pmk[MT7697_WIFI_LENGTH_PMK]; u8 pmk[MT7697_WIFI_LENGTH_PMK];
u16 ch_hint; u16 ch_hint;
struct work_struct disconnect_work; struct work_struct disconnect_work;
struct timer_list disconnect_timer; struct timer_list disconnect_timer;
...@@ -196,12 +196,12 @@ struct mt7697_vif { ...@@ -196,12 +196,12 @@ struct mt7697_vif {
static inline struct wiphy *cfg_to_wiphy(struct mt7697_cfg80211_info *cfg) static inline struct wiphy *cfg_to_wiphy(struct mt7697_cfg80211_info *cfg)
{ {
return cfg->wiphy; return cfg->wiphy;
} }
static inline struct mt7697_cfg80211_info *wiphy_to_cfg(struct wiphy *w) static inline struct mt7697_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
{ {
return (struct mt7697_cfg80211_info *)(wiphy_priv(w)); return (struct mt7697_cfg80211_info *)(wiphy_priv(w));
} }
static inline struct mt7697_cfg80211_info *mt7697_priv(struct net_device *ndev) static inline struct mt7697_cfg80211_info *mt7697_priv(struct net_device *ndev)
...@@ -211,13 +211,13 @@ static inline struct mt7697_cfg80211_info *mt7697_priv(struct net_device *ndev) ...@@ -211,13 +211,13 @@ static inline struct mt7697_cfg80211_info *mt7697_priv(struct net_device *ndev)
static inline struct mt7697_vif *mt7697_vif_from_wdev(struct wireless_dev *wdev) static inline struct mt7697_vif *mt7697_vif_from_wdev(struct wireless_dev *wdev)
{ {
return container_of(wdev, struct mt7697_vif, wdev); return container_of(wdev, struct mt7697_vif, wdev);
} }
void mt7697_init_netdev(struct net_device*); void mt7697_init_netdev(struct net_device*);
struct mt7697_vif *mt7697_get_vif_by_idx(struct mt7697_cfg80211_info*, u32); struct mt7697_vif *mt7697_get_vif_by_idx(struct mt7697_cfg80211_info*, u32);
struct wireless_dev *mt7697_interface_add(struct mt7697_cfg80211_info*, struct wireless_dev *mt7697_interface_add(struct mt7697_cfg80211_info*,
const char*, enum nl80211_iftype, u8); const char*, enum nl80211_iftype, u8);
int mt7697_notify_tx(void*, u32); int mt7697_notify_tx(void*, u32);
void mt7697_tx_stop(struct mt7697_cfg80211_info*); void mt7697_tx_stop(struct mt7697_cfg80211_info*);
......
...@@ -36,15 +36,15 @@ MODULE_PARM_DESC(itf_idx_start, "MT7697 WiFi interface start index"); ...@@ -36,15 +36,15 @@ MODULE_PARM_DESC(itf_idx_start, "MT7697 WiFi interface start index");
static void mt7697_to_lower(char** in) static void mt7697_to_lower(char** in)
{ {
char* ptr = (char*)*in; char* ptr = (char*)*in;
while (*ptr != '\0') { while (*ptr != '\0') {
if (((*ptr <= 'Z') && (*ptr >= 'A')) || if (((*ptr <= 'Z') && (*ptr >= 'A')) ||
((*ptr <= 'z') && (*ptr >= 'a'))) ((*ptr <= 'z') && (*ptr >= 'a')))
*ptr = ((*ptr <= 'Z') && (*ptr >= 'A')) ? *ptr = ((*ptr <= 'Z') && (*ptr >= 'A')) ?
*ptr + 'a' - 'A':*ptr; *ptr + 'a' - 'A':*ptr;
ptr++; ptr++;
} }
} }
static int mt7697_open(struct net_device *ndev) static int mt7697_open(struct net_device *ndev)
...@@ -55,8 +55,8 @@ static int mt7697_open(struct net_device *ndev) ...@@ -55,8 +55,8 @@ static int mt7697_open(struct net_device *ndev)
dev_dbg(cfg->dev, "%s(): open net device\n", __func__); dev_dbg(cfg->dev, "%s(): open net device\n", __func__);
if (!cfg->rxq_hdl && !cfg->txq_hdl) { if (!cfg->rxq_hdl && !cfg->txq_hdl) {
dev_dbg(cfg->dev, "%s(): open mt7697 uart\n", __func__); dev_dbg(cfg->dev, "%s(): open mt7697 uart\n", __func__);
cfg->txq_hdl = cfg->hif_ops->open(mt7697_proc_80211cmd, cfg); cfg->txq_hdl = cfg->hif_ops->open(mt7697_proc_80211cmd, cfg);
if (!cfg->txq_hdl) { if (!cfg->txq_hdl) {
dev_err(cfg->dev, "%s(): open() failed\n", __func__); dev_err(cfg->dev, "%s(): open() failed\n", __func__);
...@@ -64,15 +64,16 @@ static int mt7697_open(struct net_device *ndev) ...@@ -64,15 +64,16 @@ static int mt7697_open(struct net_device *ndev)
} }
cfg->rxq_hdl = cfg->txq_hdl; cfg->rxq_hdl = cfg->txq_hdl;
} }
set_bit(WLAN_ENABLED, &vif->flags); set_bit(WLAN_ENABLED, &vif->flags);
if (test_bit(CONNECTED, &vif->flags)) { if (test_bit(CONNECTED, &vif->flags)) {
netif_carrier_on(ndev); netif_carrier_on(ndev);
netif_wake_queue(ndev); netif_wake_queue(ndev);
} else } else {
netif_carrier_on(ndev); netif_carrier_on(ndev);
}
cleanup: cleanup:
return ret; return ret;
...@@ -89,13 +90,13 @@ static int mt7697_stop(struct net_device *ndev) ...@@ -89,13 +90,13 @@ static int mt7697_stop(struct net_device *ndev)
ret = mt7697_cfg80211_stop(vif); ret = mt7697_cfg80211_stop(vif);
if (ret < 0) { if (ret < 0) {
dev_err(cfg->dev, dev_err(cfg->dev,
"%s(): mt7697_cfg80211_stop() failed(%d)\n", "%s(): mt7697_cfg80211_stop() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
cleanup: cleanup:
return ret; return ret;
} }
...@@ -112,7 +113,7 @@ static void mt7697_set_multicast_list(struct net_device *ndev) ...@@ -112,7 +113,7 @@ static void mt7697_set_multicast_list(struct net_device *ndev)
bool mc_all_on = false; bool mc_all_on = false;
int mc_count = netdev_mc_count(ndev); int mc_count = netdev_mc_count(ndev);
dev_dbg(cfg->dev, "%s(): net device set multicast flags(0x%08x)\n", dev_dbg(cfg->dev, "%s(): net device set multicast flags(0x%08x)\n",
__func__, ndev->flags); __func__, ndev->flags);
/* Enable multicast-all filter. */ /* Enable multicast-all filter. */
...@@ -139,25 +140,25 @@ static void mt7697_set_multicast_list(struct net_device *ndev) ...@@ -139,25 +140,25 @@ static void mt7697_set_multicast_list(struct net_device *ndev)
static void mt7697_init_hw_start(struct work_struct *work) static void mt7697_init_hw_start(struct work_struct *work)
{ {
struct mt7697_cfg80211_info *cfg = container_of(work, struct mt7697_cfg80211_info *cfg = container_of(work,
struct mt7697_cfg80211_info, init_work); struct mt7697_cfg80211_info, init_work);
int err; int err;
if (!strcmp(hw_itf, "spi")) { if (!strcmp(hw_itf, "spi")) {
dev_dbg(cfg->dev, "%s(): init mt7697 queue(%u/%u)\n", dev_dbg(cfg->dev, "%s(): init mt7697 queue(%u/%u)\n",
__func__, MT7697_MAC80211_QUEUE_TX, MT7697_MAC80211_QUEUE_RX); __func__, MT7697_MAC80211_QUEUE_TX,
err = cfg->hif_ops->init(MT7697_MAC80211_QUEUE_TX, MT7697_MAC80211_QUEUE_RX);
err = cfg->hif_ops->init(MT7697_MAC80211_QUEUE_TX,
MT7697_MAC80211_QUEUE_RX, cfg, MT7697_MAC80211_QUEUE_RX, cfg,
mt7697_notify_tx, mt7697_notify_tx,
mt7697_proc_80211cmd, mt7697_proc_80211cmd,
&cfg->txq_hdl, &cfg->rxq_hdl); &cfg->txq_hdl, &cfg->rxq_hdl);
if (err < 0) { if (err < 0) {
dev_err(cfg->dev, "%s(): queue(%u) init() failed(%d)\n", dev_err(cfg->dev, "%s(): queue(%u) init() failed(%d)\n",
__func__, MT7697_MAC80211_QUEUE_TX, err); __func__, MT7697_MAC80211_QUEUE_TX, err);
goto failed; goto failed;
} }
} } else {
else {
dev_dbg(cfg->dev, "%s(): open mt7697 uart\n", __func__); dev_dbg(cfg->dev, "%s(): open mt7697 uart\n", __func__);
cfg->txq_hdl = cfg->hif_ops->open(mt7697_proc_80211cmd, cfg); cfg->txq_hdl = cfg->hif_ops->open(mt7697_proc_80211cmd, cfg);
if (!cfg->txq_hdl) { if (!cfg->txq_hdl) {
...@@ -170,7 +171,7 @@ static void mt7697_init_hw_start(struct work_struct *work) ...@@ -170,7 +171,7 @@ static void mt7697_init_hw_start(struct work_struct *work)
err = mt7697_wr_cfg_req(cfg); err = mt7697_wr_cfg_req(cfg);
if (err < 0) { if (err < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_cfg_req() failed(%d)\n", dev_err(cfg->dev, "%s(): mt7697_wr_cfg_req() failed(%d)\n",
__func__, err); __func__, err);
goto failed; goto failed;
} }
...@@ -180,28 +181,28 @@ failed: ...@@ -180,28 +181,28 @@ failed:
} }
static const struct net_device_ops mt7697_netdev_ops = { static const struct net_device_ops mt7697_netdev_ops = {
.ndo_open = mt7697_open, .ndo_open = mt7697_open,
.ndo_stop = mt7697_stop, .ndo_stop = mt7697_stop,
.ndo_start_xmit = mt7697_data_tx, .ndo_start_xmit = mt7697_data_tx,
.ndo_get_stats = mt7697_get_stats, .ndo_get_stats = mt7697_get_stats,
.ndo_set_rx_mode = mt7697_set_multicast_list, .ndo_set_rx_mode = mt7697_set_multicast_list,
}; };
void mt7697_init_netdev(struct net_device *ndev) void mt7697_init_netdev(struct net_device *ndev)
{ {
ndev->netdev_ops = &mt7697_netdev_ops; ndev->netdev_ops = &mt7697_netdev_ops;
ndev->wireless_handlers = &mt7697_wireless_hndlrs; ndev->wireless_handlers = &mt7697_wireless_hndlrs;
ndev->destructor = free_netdev; ndev->destructor = free_netdev;
ndev->watchdog_timeo = MT7697_TX_TIMEOUT; ndev->watchdog_timeo = MT7697_TX_TIMEOUT;
ndev->needed_headroom = sizeof(struct ieee80211_hdr) + ndev->needed_headroom = sizeof(struct ieee80211_hdr) +
sizeof(struct mt7697_llc_snap_hdr); sizeof(struct mt7697_llc_snap_hdr);
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
} }
static struct mt7697_if_ops if_ops; static struct mt7697_if_ops if_ops;
static int mt7697_probe(struct platform_device *pdev) static int mt7697_probe(struct platform_device *pdev)
{ {
struct wiphy *wiphy; struct wiphy *wiphy;
struct mt7697_cfg80211_info *cfg; struct mt7697_cfg80211_info *cfg;
int err = 0; int err = 0;
...@@ -209,22 +210,22 @@ static int mt7697_probe(struct platform_device *pdev) ...@@ -209,22 +210,22 @@ static int mt7697_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s(): probe\n", __func__); dev_dbg(&pdev->dev, "%s(): probe\n", __func__);
cfg = mt7697_cfg80211_create(); cfg = mt7697_cfg80211_create();
if (!cfg) { if (!cfg) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%s(): mt7697_cfg80211_create() failed()\n", "%s(): mt7697_cfg80211_create() failed()\n",
__func__); __func__);
err = -ENOMEM; err = -ENOMEM;
goto failed; goto failed;
} }
sema_init(&cfg->sem, 1); sema_init(&cfg->sem, 1);
cfg->tx_workq = create_workqueue(DRVNAME); cfg->tx_workq = create_workqueue(DRVNAME);
if (!cfg->tx_workq) { if (!cfg->tx_workq) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%s(): create_workqueue() failed()\n", "%s(): create_workqueue() failed()\n",
__func__); __func__);
err = -ENOMEM; err = -ENOMEM;
goto failed; goto failed;
} }
INIT_WORK(&cfg->init_work, mt7697_init_hw_start); INIT_WORK(&cfg->init_work, mt7697_init_hw_start);
INIT_WORK(&cfg->tx_work, mt7697_tx_work); INIT_WORK(&cfg->tx_work, mt7697_tx_work);
...@@ -245,16 +246,14 @@ static int mt7697_probe(struct platform_device *pdev) ...@@ -245,16 +246,14 @@ static int mt7697_probe(struct platform_device *pdev)
if_ops.read = mt7697q_read; if_ops.read = mt7697q_read;
if_ops.write = mt7697q_write; if_ops.write = mt7697q_write;
if_ops.unblock_writer = mt7697q_unblock_writer; if_ops.unblock_writer = mt7697q_unblock_writer;
} } else if (!strcmp(hw_itf, "uart")) {
else if (!strcmp(hw_itf, "uart")) {
if_ops.open = mt7697_uart_open; if_ops.open = mt7697_uart_open;
if_ops.close = mt7697_uart_close; if_ops.close = mt7697_uart_close;
if_ops.read = mt7697_uart_read; if_ops.read = mt7697_uart_read;
if_ops.write = mt7697_uart_write; if_ops.write = mt7697_uart_write;
} } else {
else { dev_err(&pdev->dev,
dev_err(&pdev->dev, "%s(): invalid hw itf(spi/uart) module paramter('%s')\n",
"%s(): invalid hw itf(spi/uart) module paramter('%s')\n",
__func__, hw_itf); __func__, hw_itf);
err = -EINVAL; err = -EINVAL;
goto failed; goto failed;
...@@ -269,15 +268,15 @@ static int mt7697_probe(struct platform_device *pdev) ...@@ -269,15 +268,15 @@ static int mt7697_probe(struct platform_device *pdev)
err = mt7697_cfg80211_init(cfg); err = mt7697_cfg80211_init(cfg);
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%s(): mt7697_cfg80211_init() failed(%d)\n", "%s(): mt7697_cfg80211_init() failed(%d)\n",
__func__, err); __func__, err);
goto failed; goto failed;
} }
platform_set_drvdata(pdev, cfg); platform_set_drvdata(pdev, cfg);
schedule_work(&cfg->init_work); schedule_work(&cfg->init_work);
failed: failed:
if (err < 0) { if (err < 0) {
if (wiphy) wiphy_free(wiphy); if (wiphy) wiphy_free(wiphy);
...@@ -303,20 +302,20 @@ static void mt7697_release(struct device *dev) ...@@ -303,20 +302,20 @@ static void mt7697_release(struct device *dev)
} }
static struct platform_device mt7697_platform_device = { static struct platform_device mt7697_platform_device = {
.name = DRVNAME, .name = DRVNAME,
.id = PLATFORM_DEVID_NONE, .id = PLATFORM_DEVID_NONE,
.dev = { .dev = {
.release = mt7697_release, .release = mt7697_release,
}, },
}; };
static struct platform_driver mt7697_platform_driver = { static struct platform_driver mt7697_platform_driver = {
.driver = { .driver = {
.name = DRVNAME, .name = DRVNAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = mt7697_probe, .probe = mt7697_probe,
.remove = mt7697_remove, .remove = mt7697_remove,
}; };
...@@ -327,14 +326,14 @@ static int __init mt7697_init(void) ...@@ -327,14 +326,14 @@ static int __init mt7697_init(void)
pr_info(DRVNAME" init\n"); pr_info(DRVNAME" init\n");
ret = platform_device_register(&mt7697_platform_device); ret = platform_device_register(&mt7697_platform_device);
if (ret) { if (ret) {
pr_err(DRVNAME" %s(): platform_device_register() failed(%d)\n", pr_err(DRVNAME" %s(): platform_device_register() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
ret = platform_driver_register(&mt7697_platform_driver); ret = platform_driver_register(&mt7697_platform_driver);
if (ret) { if (ret) {
pr_err(DRVNAME" %s(): platform_driver_register() failed(%d)\n", pr_err(DRVNAME" %s(): platform_driver_register() failed(%d)\n",
__func__, ret); __func__, ret);
platform_device_del(&mt7697_platform_device); platform_device_del(&mt7697_platform_device);
goto cleanup; goto cleanup;
...@@ -374,16 +373,16 @@ int mt7697_disconnect(struct mt7697_vif *vif) ...@@ -374,16 +373,16 @@ int mt7697_disconnect(struct mt7697_vif *vif)
if (test_bit(CONNECTED, &vif->flags) || if (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags)) { test_bit(CONNECT_PEND, &vif->flags)) {
if (vif->sme_state == SME_CONNECTING) if (vif->sme_state == SME_CONNECTING) {
cfg80211_connect_result(vif->ndev, vif->bssid, cfg80211_connect_result(vif->ndev, vif->bssid,
NULL, 0, NULL, 0,
NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL); GFP_KERNEL);
else if (vif->sme_state == SME_CONNECTED) { } else if (vif->sme_state == SME_CONNECTED) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,44) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,44)
cfg80211_disconnected(vif->ndev, 0, cfg80211_disconnected(vif->ndev, 0,
NULL, 0, vif->locally_generated, NULL, 0, vif->locally_generated,
GFP_KERNEL); GFP_KERNEL);
#else #else
cfg80211_disconnected(vif->ndev, 0, cfg80211_disconnected(vif->ndev, 0,
...@@ -393,8 +392,8 @@ int mt7697_disconnect(struct mt7697_vif *vif) ...@@ -393,8 +392,8 @@ int mt7697_disconnect(struct mt7697_vif *vif)
ret = mt7697_wr_disconnect_req(vif->cfg, NULL); ret = mt7697_wr_disconnect_req(vif->cfg, NULL);
if (ret < 0) { if (ret < 0) {
dev_err(vif->cfg->dev, dev_err(vif->cfg->dev,
"%s(): mt7697_wr_disconnect_req() failed(%d)\n", "%s(): mt7697_wr_disconnect_req() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
...@@ -414,4 +413,3 @@ cleanup: ...@@ -414,4 +413,3 @@ cleanup:
MODULE_AUTHOR("Sierra Wireless Corporation"); MODULE_AUTHOR("Sierra Wireless Corporation");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek7697 WiFi 80211"); MODULE_DESCRIPTION("MediaTek7697 WiFi 80211");
...@@ -7,7 +7,7 @@ export CLIENT_REF="0x10000001" ...@@ -7,7 +7,7 @@ export CLIENT_REF="0x10000001"
export PASSPHRASE="@iPr1m3" export PASSPHRASE="@iPr1m3"
export SECURITY_PROTO="3" export SECURITY_PROTO="3"
echo "Start wifi client..." echo "Start wifi client..."
wifi client start $ITF_LAN wifi client start $ITF_LAN
echo "Begin wifi client scan..." echo "Begin wifi client scan..."
......
...@@ -25,13 +25,14 @@ int mt7697_notify_tx(void* priv, u32 free) ...@@ -25,13 +25,14 @@ int mt7697_notify_tx(void* priv, u32 free)
spin_lock_bh(&cfg->tx_skb_list_lock); spin_lock_bh(&cfg->tx_skb_list_lock);
if (!list_empty(&cfg->tx_skb_list)) { if (!list_empty(&cfg->tx_skb_list)) {
struct mt7697_tx_pkt *tx_pkt = list_entry(&cfg->tx_skb_list, struct mt7697_tx_pkt *tx_pkt = list_entry(&cfg->tx_skb_list,
struct mt7697_tx_pkt, next); struct mt7697_tx_pkt, next);
if (tx_pkt->skb->len >= free) { if (tx_pkt->skb->len >= free) {
cfg->hif_ops->unblock_writer(cfg->txq_hdl); cfg->hif_ops->unblock_writer(cfg->txq_hdl);
ret = queue_work(cfg->tx_workq, &cfg->tx_work); ret = queue_work(cfg->tx_workq, &cfg->tx_work);
if (ret < 0) { if (ret < 0) {
dev_err(cfg->dev, "%s(): queue_work() failed(%d)\n", dev_err(cfg->dev,
"%s(): queue_work() failed(%d)\n",
__func__, ret); __func__, ret);
goto cleanup; goto cleanup;
} }
...@@ -52,7 +53,7 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev) ...@@ -52,7 +53,7 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
dev_dbg(cfg->dev, "%s(): tx len(%u)\n", __func__, skb->len); dev_dbg(cfg->dev, "%s(): tx len(%u)\n", __func__, skb->len);
dev_dbg(cfg->dev, "%s(): headroom skb/needed(%u/%u)\n", dev_dbg(cfg->dev, "%s(): headroom skb/needed(%u/%u)\n",
__func__, skb_headroom(skb), ndev->needed_headroom); __func__, skb_headroom(skb), ndev->needed_headroom);
if (skb_headroom(skb) < ndev->needed_headroom) { if (skb_headroom(skb) < ndev->needed_headroom) {
struct sk_buff *tmp_skb = skb; struct sk_buff *tmp_skb = skb;
...@@ -67,18 +68,18 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev) ...@@ -67,18 +68,18 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
tx_skb = &cfg->tx_skb_pool[atomic_read(&cfg->tx_skb_pool_idx)]; tx_skb = &cfg->tx_skb_pool[atomic_read(&cfg->tx_skb_pool_idx)];
if (tx_skb->skb) { if (tx_skb->skb) {
dev_warn(cfg->dev, "%s(): tx pool full\n", dev_warn(cfg->dev, "%s(): tx pool full\n",
__func__); __func__);
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_BUSY;
goto cleanup; goto cleanup;
} }
tx_skb->skb = skb; tx_skb->skb = skb;
dev_dbg(cfg->dev, "%s(): tx pkt(%u/%p)\n", dev_dbg(cfg->dev, "%s(): tx pkt(%u/%p)\n",
__func__, atomic_read(&cfg->tx_skb_pool_idx), tx_skb->skb); __func__, atomic_read(&cfg->tx_skb_pool_idx), tx_skb->skb);
atomic_inc(&cfg->tx_skb_pool_idx); atomic_inc(&cfg->tx_skb_pool_idx);
if (atomic_read(&cfg->tx_skb_pool_idx) >= MT7697_TX_PKT_POOL_LEN) if (atomic_read(&cfg->tx_skb_pool_idx) >= MT7697_TX_PKT_POOL_LEN)
atomic_set(&cfg->tx_skb_pool_idx, 0); atomic_set(&cfg->tx_skb_pool_idx, 0);
spin_lock_bh(&cfg->tx_skb_list_lock); spin_lock_bh(&cfg->tx_skb_list_lock);
...@@ -87,7 +88,7 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev) ...@@ -87,7 +88,7 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
ret = queue_work(cfg->tx_workq, &cfg->tx_work); ret = queue_work(cfg->tx_workq, &cfg->tx_work);
if (ret < 0) { if (ret < 0) {
dev_err(cfg->dev, "%s(): queue_work() failed(%d)\n", dev_err(cfg->dev, "%s(): queue_work() failed(%d)\n",
__func__, ret); __func__, ret);
ret = NETDEV_TX_BUSY; ret = NETDEV_TX_BUSY;
goto cleanup; goto cleanup;
...@@ -105,7 +106,7 @@ cleanup: ...@@ -105,7 +106,7 @@ cleanup:
void mt7697_tx_work(struct work_struct *work) void mt7697_tx_work(struct work_struct *work)
{ {
struct mt7697_cfg80211_info *cfg = container_of(work, struct mt7697_cfg80211_info *cfg = container_of(work,
struct mt7697_cfg80211_info, tx_work); struct mt7697_cfg80211_info, tx_work);
struct mt7697_tx_pkt *tx_pkt, *tx_pkt_next = NULL; struct mt7697_tx_pkt *tx_pkt, *tx_pkt_next = NULL;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
...@@ -115,23 +116,24 @@ void mt7697_tx_work(struct work_struct *work) ...@@ -115,23 +116,24 @@ void mt7697_tx_work(struct work_struct *work)
struct mt7697_vif *vif = netdev_priv(tx_pkt->skb->dev); struct mt7697_vif *vif = netdev_priv(tx_pkt->skb->dev);
WARN_ON(!vif); WARN_ON(!vif);
/* validate length for ether packet */ /* validate length for ether packet */
if (tx_pkt->skb->len < sizeof(*hdr)) { if (tx_pkt->skb->len < sizeof(*hdr)) {
dev_err(cfg->dev, "%s(): invalid skb len(%u < %u)\n", dev_err(cfg->dev, "%s(): invalid skb len(%u < %u)\n",
__func__, tx_pkt->skb->len, sizeof(*hdr)); __func__, tx_pkt->skb->len, sizeof(*hdr));
vif->net_stats.tx_errors++; vif->net_stats.tx_errors++;
} }
ret = mt7697_wr_tx_raw_packet(cfg, tx_pkt->skb->data, ret = mt7697_wr_tx_raw_packet(cfg, tx_pkt->skb->data,
tx_pkt->skb->len); tx_pkt->skb->len);
if (ret < 0) { if (ret < 0) {
dev_dbg(cfg->dev, dev_dbg(cfg->dev,
"%s(): mt7697_wr_tx_raw_packet() failed(%d)\n", "%s(): mt7697_wr_tx_raw_packet() failed(%d)\n",
__func__, ret); __func__, ret);
vif->net_stats.tx_errors++; vif->net_stats.tx_errors++;
} }
dev_dbg(cfg->dev, "%s(): tx complete pkt(%p)\n", __func__, tx_pkt->skb); dev_dbg(cfg->dev, "%s(): tx complete pkt(%p)\n", __func__,
tx_pkt->skb);
vif->net_stats.tx_packets++; vif->net_stats.tx_packets++;
vif->net_stats.tx_bytes += tx_pkt->skb->len; vif->net_stats.tx_bytes += tx_pkt->skb->len;
...@@ -148,13 +150,14 @@ void mt7697_tx_work(struct work_struct *work) ...@@ -148,13 +150,14 @@ void mt7697_tx_work(struct work_struct *work)
void mt7697_tx_stop(struct mt7697_cfg80211_info *cfg) void mt7697_tx_stop(struct mt7697_cfg80211_info *cfg)
{ {
struct mt7697_tx_pkt *tx_pkt, *tx_pkt_next = NULL; struct mt7697_tx_pkt *tx_pkt, *tx_pkt_next = NULL;
list_for_each_entry_safe(tx_pkt, tx_pkt_next, &cfg->tx_skb_list, next) { list_for_each_entry_safe(tx_pkt, tx_pkt_next, &cfg->tx_skb_list, next) {
struct mt7697_vif *vif = netdev_priv(tx_pkt->skb->dev); struct mt7697_vif *vif = netdev_priv(tx_pkt->skb->dev);
WARN_ON(!vif); WARN_ON(!vif);
dev_dbg(cfg->dev, "%s(): tx drop pkt(%p)\n", __func__, tx_pkt->skb); dev_dbg(cfg->dev, "%s(): tx drop pkt(%p)\n", __func__,
tx_pkt->skb);
vif->net_stats.tx_dropped++; vif->net_stats.tx_dropped++;
spin_lock_bh(&cfg->tx_skb_list_lock); spin_lock_bh(&cfg->tx_skb_list_lock);
...@@ -186,7 +189,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx) ...@@ -186,7 +189,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
} }
if ((len < sizeof(*hdr)) || (len > IEEE80211_MAX_FRAME_LEN)) { if ((len < sizeof(*hdr)) || (len > IEEE80211_MAX_FRAME_LEN)) {
dev_warn(cfg->dev, "%s(): invalid Rx frame size(%u)\n", dev_warn(cfg->dev, "%s(): invalid Rx frame size(%u)\n",
__func__, len); __func__, len);
vif->net_stats.rx_length_errors++; vif->net_stats.rx_length_errors++;
ret = -EINVAL; ret = -EINVAL;
...@@ -201,7 +204,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx) ...@@ -201,7 +204,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
} }
skb_put(skb, len); skb_put(skb, len);
memcpy(skb->data, cfg->rx_data, len); memcpy(skb->data, cfg->rx_data, len);
skb->dev = vif->ndev; skb->dev = vif->ndev;
vif->net_stats.rx_packets++; vif->net_stats.rx_packets++;
...@@ -209,7 +212,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx) ...@@ -209,7 +212,7 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
skb->protocol = eth_type_trans(skb, skb->dev); skb->protocol = eth_type_trans(skb, skb->dev);
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
dev_dbg(cfg->dev, "%s(): rx frame protocol(%u) type(%u)\n", dev_dbg(cfg->dev, "%s(): rx frame protocol(%u) type(%u)\n",
__func__, skb->protocol, skb->pkt_type); __func__, skb->protocol, skb->pkt_type);
ret = netif_rx_ni(skb); ret = netif_rx_ni(skb);
...@@ -221,7 +224,8 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx) ...@@ -221,7 +224,8 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
goto cleanup; goto cleanup;
} }
dev_err(cfg->dev, "%s(): netif_rx_ni() failed(%d)\n", __func__, ret); dev_err(cfg->dev, "%s(): netif_rx_ni() failed(%d)\n", __func__,
ret);
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment