Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
Felix Fietkau committed Nov 20, 2014
0 parents commit 9e7049b
Show file tree
Hide file tree
Showing 25 changed files with 6,823 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
EXTRA_CFLAGS += -Werror

obj-m := mt76pci.o

mt76pci-y := \
pci.o dma.o \
main.o init.o debugfs.o tx.o util.o \
core.o mac.o eeprom.o mcu.o phy.o \
trace.o
132 changes: 132 additions & 0 deletions core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (C) 2014 Felix Fietkau <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/delay.h>
#include "mt76.h"
#include "trace.h"

bool mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
int timeout)
{
u32 cur;

timeout /= 10;
do {
cur = mt76_rr(dev, offset) & mask;
if (cur == val)
return true;

udelay(10);
} while (timeout-- > 0);

return false;
}

bool mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
int timeout)
{
u32 cur;

timeout /= 10;
do {
cur = mt76_rr(dev, offset) & mask;
if (cur == val)
return true;

msleep(10);
} while (timeout-- > 0);

return false;
}

void mt76_write_reg_pairs(struct mt76_dev *dev,
const struct mt76_reg_pair *data, int len)
{
while (len > 0) {
mt76_wr(dev, data->reg, data->value);
len--;
data++;
}
}

void mt76_set_irq_mask(struct mt76_dev *dev, u32 clear, u32 set)
{
unsigned long flags;

spin_lock_irqsave(&dev->irq_lock, flags);
dev->irqmask &= ~clear;
dev->irqmask |= set;
mt76_wr(dev, MT_INT_MASK_CSR, dev->irqmask);
spin_unlock_irqrestore(&dev->irq_lock, flags);
}

irqreturn_t mt76_irq_handler(int irq, void *dev_instance)
{
struct mt76_dev *dev = dev_instance;
u32 intr;

intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
mt76_wr(dev, MT_INT_SOURCE_CSR, intr);

if (!test_bit(MT76_STATE_INITAILIZED, &dev->state))
return IRQ_NONE;

trace_dev_irq(dev, intr, dev->irqmask);

intr &= dev->irqmask;

if (intr & MT_INT_TX_DONE_ALL) {
mt76_irq_disable(dev, MT_INT_TX_DONE_ALL);
tasklet_schedule(&dev->tx_tasklet);
}

if (intr & MT_INT_RX_DONE(0)) {
mt76_irq_disable(dev, MT_INT_RX_DONE(0));
napi_schedule(&dev->napi);
}

if (intr & MT_INT_RX_DONE(1)) {
mt76_irq_disable(dev, MT_INT_RX_DONE(1));
tasklet_schedule(&dev->rx_tasklet);
}

if (intr & MT_INT_PRE_TBTT)
tasklet_schedule(&dev->pre_tbtt_tasklet);

/* send buffered multicast frames now */
if (intr & MT_INT_TBTT)
mt76_kick_queue(dev, &dev->q_tx[MT_TXQ_PSD]);

if (intr & MT_INT_TX_STAT) {
mt76_mac_poll_tx_status(dev, true);
tasklet_schedule(&dev->tx_tasklet);
}

return IRQ_HANDLED;
}

int mt76_set_channel(struct mt76_dev *dev, struct cfg80211_chan_def *chandef)
{
int ret;

tasklet_disable(&dev->pre_tbtt_tasklet);
cancel_delayed_work_sync(&dev->cal_work);

mt76_mac_stop(dev, true);
ret = mt76_phy_set_channel(dev, chandef);
mt76_mac_resume(dev);
tasklet_enable(&dev->pre_tbtt_tasklet);

return ret;
}

89 changes: 89 additions & 0 deletions debugfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2014 Felix Fietkau <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/debugfs.h>
#include "mt76.h"

static int
mt76_reg_set(void *data, u64 val)
{
struct mt76_dev *dev = data;

mt76_wr(dev, dev->debugfs_reg, val);
return 0;
}

static int
mt76_reg_get(void *data, u64 *val)
{
struct mt76_dev *dev = data;

*val = mt76_rr(dev, dev->debugfs_reg);
return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(fops_regval, mt76_reg_get, mt76_reg_set, "0x%08llx\n");


static int
mt76_ampdu_stat_read(struct seq_file *file, void *data)
{
struct mt76_dev *dev = file->private;
int i, j;

for (i = 0; i < 4; i++) {
seq_puts(file, "Length: ");
for (j = 0; j < 8; j++)
seq_printf(file, "%8d | ", i * 8 + j + 1);
seq_puts(file, "\n");
seq_puts(file, "Count: ");
for (j = 0; j < 8; j++)
seq_printf(file, "%8d | ", dev->aggr_stats[i * 8 + j]);
seq_puts(file, "\n");
seq_puts(file, "--------");
for (j = 0; j < 8; j++)
seq_puts(file, "-----------");
seq_puts(file, "\n");
}

return 0;
}

static int
mt76_ampdu_stat_open(struct inode *inode, struct file *f)
{
return single_open(f, mt76_ampdu_stat_read, inode->i_private);
}

static const struct file_operations fops_ampdu_stat = {
.open = mt76_ampdu_stat_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

void mt76_init_debugfs(struct mt76_dev *dev)
{
struct dentry *dir;

dir = debugfs_create_dir("mt76", dev->hw->wiphy->debugfsdir);
if (!dir)
return;

debugfs_create_blob("eeprom", S_IRUSR, dir, &dev->eeprom);
debugfs_create_u8("temperature", S_IRUSR, dir, &dev->cal.temp);

debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg);
debugfs_create_file("regval", S_IRUSR | S_IWUSR, dir, dev, &fops_regval);
debugfs_create_file("ampdu_stat", S_IRUSR, dir, dev, &fops_ampdu_stat);
}
Loading

0 comments on commit 9e7049b

Please sign in to comment.