mt76: Introduce mt76_mcu data structure

Introduce mt76_mcu data structure to contain common fields between
mt76u_mcu and mt76e_mcu.
Initialize mcu common fields in mt76_alloc_device().
Rely on mt76_mcu in mt76_mcu_rx_event and in mt76_mcu_get_response
in order to reuse them in usb code

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Lorenzo Bianconi 2020-02-08 13:44:28 +01:00 committed by Felix Fietkau
parent a9fddf08ec
commit 0987295750
12 changed files with 48 additions and 54 deletions

View file

@ -420,6 +420,10 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
init_waitqueue_head(&dev->tx_wait);
skb_queue_head_init(&dev->status_list);
skb_queue_head_init(&dev->mcu.res_q);
init_waitqueue_head(&dev->mcu.wait);
mutex_init(&dev->mcu.mutex);
INIT_LIST_HEAD(&dev->txwi_cache);
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)

View file

@ -24,7 +24,6 @@ mt76_mcu_msg_alloc(const void *data, int head_len,
}
EXPORT_SYMBOL_GPL(mt76_mcu_msg_alloc);
/* mmio */
struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev,
unsigned long expires)
{
@ -34,17 +33,17 @@ struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev,
return NULL;
timeout = expires - jiffies;
wait_event_timeout(dev->mmio.mcu.wait,
(!skb_queue_empty(&dev->mmio.mcu.res_q) ||
wait_event_timeout(dev->mcu.wait,
(!skb_queue_empty(&dev->mcu.res_q) ||
test_bit(MT76_MCU_RESET, &dev->phy.state)),
timeout);
return skb_dequeue(&dev->mmio.mcu.res_q);
return skb_dequeue(&dev->mcu.res_q);
}
EXPORT_SYMBOL_GPL(mt76_mcu_get_response);
void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb)
{
skb_queue_tail(&dev->mmio.mcu.res_q, skb);
wake_up(&dev->mmio.mcu.wait);
skb_queue_tail(&dev->mcu.res_q, skb);
wake_up(&dev->mcu.wait);
}
EXPORT_SYMBOL_GPL(mt76_mcu_rx_event);

View file

@ -94,9 +94,6 @@ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
dev->bus = &mt76_mmio_ops;
dev->mmio.regs = regs;
skb_queue_head_init(&dev->mmio.mcu.res_q);
init_waitqueue_head(&dev->mmio.mcu.wait);
spin_lock_init(&dev->mmio.irq_lock);
mutex_init(&dev->mmio.mcu.mutex);
}
EXPORT_SYMBOL_GPL(mt76_mmio_init);

View file

@ -388,6 +388,14 @@ enum mt76u_out_ep {
__MT_EP_OUT_MAX,
};
struct mt76_mcu {
struct mutex mutex;
u32 msg_seq;
struct sk_buff_head res_q;
wait_queue_head_t wait;
};
#define MT_TX_SG_MAX_SIZE 8
#define MT_RX_SG_MAX_SIZE 4
#define MT_NUM_TX_ENTRIES 256
@ -408,10 +416,7 @@ struct mt76_usb {
bool sg_en;
struct mt76u_mcu {
struct mutex mutex;
u8 *data;
u32 msg_seq;
/* multiple reads */
struct mt76_reg_pair *rp;
int rp_len;
@ -421,14 +426,6 @@ struct mt76_usb {
};
struct mt76_mmio {
struct mt76e_mcu {
struct mutex mutex;
wait_queue_head_t wait;
struct sk_buff_head res_q;
u32 msg_seq;
} mcu;
void __iomem *regs;
spinlock_t irq_lock;
u32 irqmask;
@ -506,6 +503,8 @@ struct mt76_dev {
const struct mt76_mcu_ops *mcu_ops;
struct device *dev;
struct mt76_mcu mcu;
struct net_device napi_dev;
spinlock_t rx_lock;
struct napi_struct napi[__MT_RXQ_MAX];

View file

@ -22,9 +22,9 @@ __mt7603_mcu_msg_send(struct mt7603_dev *dev, struct sk_buff *skb,
struct mt7603_mcu_txd *txd;
u8 seq;
seq = ++mdev->mmio.mcu.msg_seq & 0xf;
seq = ++mdev->mcu.msg_seq & 0xf;
if (!seq)
seq = ++mdev->mmio.mcu.msg_seq & 0xf;
seq = ++mdev->mcu.msg_seq & 0xf;
txd = (struct mt7603_mcu_txd *)skb_push(skb, hdrlen);
memset(txd, 0, hdrlen);
@ -67,7 +67,7 @@ mt7603_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
if (!skb)
return -ENOMEM;
mutex_lock(&mdev->mmio.mcu.mutex);
mutex_lock(&mdev->mcu.mutex);
ret = __mt7603_mcu_msg_send(dev, skb, cmd, &seq);
if (ret)
@ -97,7 +97,7 @@ mt7603_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
}
out:
mutex_unlock(&mdev->mmio.mcu.mutex);
mutex_unlock(&mdev->mcu.mutex);
return ret;
}
@ -277,7 +277,7 @@ int mt7603_mcu_init(struct mt7603_dev *dev)
void mt7603_mcu_exit(struct mt7603_dev *dev)
{
__mt76_mcu_restart(&dev->mt76);
skb_queue_purge(&dev->mt76.mmio.mcu.res_q);
skb_queue_purge(&dev->mt76.mcu.res_q);
}
int mt7603_mcu_set_eeprom(struct mt7603_dev *dev)

View file

@ -1878,7 +1878,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mmio.mcu.wait);
wake_up(&dev->mt76.mcu.wait);
cancel_delayed_work_sync(&dev->mt76.mac_work);
/* lock/unlock all queues to ensure that no tx is pending */

View file

@ -58,9 +58,9 @@ static int __mt7615_mcu_msg_send(struct mt7615_dev *dev, struct sk_buff *skb,
u32 val;
__le32 *txd;
seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf;
seq = ++dev->mt76.mcu.msg_seq & 0xf;
if (!seq)
seq = ++dev->mt76.mmio.mcu.msg_seq & 0xf;
seq = ++dev->mt76.mcu.msg_seq & 0xf;
mcu_txd = (struct mt7615_mcu_txd *)skb_push(skb,
sizeof(struct mt7615_mcu_txd));
@ -153,7 +153,7 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
if (!skb)
return -ENOMEM;
mutex_lock(&mdev->mmio.mcu.mutex);
mutex_lock(&mdev->mcu.mutex);
ret = __mt7615_mcu_msg_send(dev, skb, cmd, &seq);
if (ret)
@ -174,7 +174,7 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
}
out:
mutex_unlock(&mdev->mmio.mcu.mutex);
mutex_unlock(&mdev->mcu.mutex);
return ret;
}
@ -719,7 +719,7 @@ void mt7615_mcu_exit(struct mt7615_dev *dev)
{
__mt76_mcu_restart(&dev->mt76);
mt7615_firmware_own(dev);
skb_queue_purge(&dev->mt76.mmio.mcu.res_q);
skb_queue_purge(&dev->mt76.mcu.res_q);
}
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev)

View file

@ -24,11 +24,11 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
if (!skb)
return -ENOMEM;
mutex_lock(&mdev->mmio.mcu.mutex);
mutex_lock(&mdev->mcu.mutex);
seq = ++mdev->mmio.mcu.msg_seq & 0xf;
seq = ++mdev->mcu.msg_seq & 0xf;
if (!seq)
seq = ++mdev->mmio.mcu.msg_seq & 0xf;
seq = ++mdev->mcu.msg_seq & 0xf;
tx_info = MT_MCU_MSG_TYPE_CMD |
FIELD_PREP(MT_MCU_MSG_CMD_TYPE, cmd) |
@ -65,7 +65,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
}
out:
mutex_unlock(&mdev->mmio.mcu.mutex);
mutex_unlock(&mdev->mcu.mutex);
return ret;
}
@ -141,7 +141,7 @@ int mt76x02_mcu_cleanup(struct mt76x02_dev *dev)
mt76_wr(dev, MT_MCU_INT_LEVEL, 1);
usleep_range(20000, 30000);
while ((skb = skb_dequeue(&dev->mt76.mmio.mcu.res_q)) != NULL)
while ((skb = skb_dequeue(&dev->mt76.mcu.res_q)) != NULL)
dev_kfree_skb(skb);
return 0;

View file

@ -544,9 +544,9 @@ static void mt76x02_check_tx_hang(struct mt76x02_dev *dev)
restart:
mt76x02_watchdog_reset(dev);
mutex_lock(&dev->mt76.mmio.mcu.mutex);
mutex_lock(&dev->mt76.mcu.mutex);
dev->mcu_timeout = 0;
mutex_unlock(&dev->mt76.mmio.mcu.mutex);
mutex_unlock(&dev->mt76.mcu.mutex);
dev->tx_hang_reset++;
dev->tx_hang_check = 0;

View file

@ -39,7 +39,6 @@ void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
void *rxwi = skb->data;
if (q == MT_RXQ_MCU) {
/* this is used just by mmio code */
mt76_mcu_rx_event(&dev->mt76, skb);
return;
}

View file

@ -83,18 +83,17 @@ static int
__mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
int cmd, bool wait_resp)
{
struct mt76_usb *usb = &dev->usb;
int ret;
u8 seq = 0;
u32 info;
int ret;
if (test_bit(MT76_REMOVED, &dev->phy.state))
return 0;
if (wait_resp) {
seq = ++usb->mcu.msg_seq & 0xf;
seq = ++dev->mcu.msg_seq & 0xf;
if (!seq)
seq = ++usb->mcu.msg_seq & 0xf;
seq = ++dev->mcu.msg_seq & 0xf;
}
info = FIELD_PREP(MT_MCU_MSG_CMD_SEQ, seq) |
@ -121,7 +120,6 @@ static int
mt76x02u_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data,
int len, bool wait_resp)
{
struct mt76_usb *usb = &dev->usb;
struct sk_buff *skb;
int err;
@ -129,9 +127,9 @@ mt76x02u_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data,
if (!skb)
return -ENOMEM;
mutex_lock(&usb->mcu.mutex);
mutex_lock(&dev->mcu.mutex);
err = __mt76x02u_mcu_send_msg(dev, skb, cmd, wait_resp);
mutex_unlock(&usb->mcu.mutex);
mutex_unlock(&dev->mcu.mutex);
return err;
}
@ -145,9 +143,8 @@ static int
mt76x02u_mcu_wr_rp(struct mt76_dev *dev, u32 base,
const struct mt76_reg_pair *data, int n)
{
const int CMD_RANDOM_WRITE = 12;
const int max_vals_per_cmd = MT_INBAND_PACKET_MAX_LEN / 8;
struct mt76_usb *usb = &dev->usb;
const int CMD_RANDOM_WRITE = 12;
struct sk_buff *skb;
int cnt, i, ret;
@ -166,9 +163,9 @@ mt76x02u_mcu_wr_rp(struct mt76_dev *dev, u32 base,
skb_put_le32(skb, data[i].value);
}
mutex_lock(&usb->mcu.mutex);
mutex_lock(&dev->mcu.mutex);
ret = __mt76x02u_mcu_send_msg(dev, skb, CMD_RANDOM_WRITE, cnt == n);
mutex_unlock(&usb->mcu.mutex);
mutex_unlock(&dev->mcu.mutex);
if (ret)
return ret;
@ -202,7 +199,7 @@ mt76x02u_mcu_rd_rp(struct mt76_dev *dev, u32 base,
skb_put_le32(skb, data[i].value);
}
mutex_lock(&usb->mcu.mutex);
mutex_lock(&dev->mcu.mutex);
usb->mcu.rp = data;
usb->mcu.rp_len = n;
@ -213,7 +210,7 @@ mt76x02u_mcu_rd_rp(struct mt76_dev *dev, u32 base,
usb->mcu.rp = NULL;
mutex_unlock(&usb->mcu.mutex);
mutex_unlock(&dev->mcu.mutex);
return ret;
}

View file

@ -1167,14 +1167,13 @@ int mt76u_init(struct mt76_dev *dev,
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
if (usb->data_len < 32)
usb->data_len = 32;
usb->data = devm_kmalloc(dev->dev, usb->data_len, GFP_KERNEL);
if (!usb->data) {
mt76u_deinit(dev);
return -ENOMEM;
}
mutex_init(&usb->mcu.mutex);
mutex_init(&usb->usb_ctrl_mtx);
dev->bus = &mt76u_ops;
dev->queue_ops = &usb_queue_ops;