summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2019-11-23 12:00:54 -0800
committerJakub Kicinski <jakub.kicinski@netronome.com>2019-11-23 12:00:54 -0800
commit3a06ee33963dea642d38c04ed18d2a5f4fdc78fd (patch)
treeffc0bd67c2dd3887cb0e5abe9c7c80156b074b05 /drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
parent72a2707a8743b62f9493e46af300f0cee4485d46 (diff)
parent05d6c8cfdbd6cefac6b373bad72775fcc4193c80 (diff)
downloadlinux-3a06ee33963dea642d38c04ed18d2a5f4fdc78fd.tar.bz2
Merge tag 'wireless-drivers-next-2019-11-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for v5.5 Last set of patches for v5.5. Major features here 802.11ax support for qtnfmac and airtime fairness support to mt76. And naturally smaller fixes and improvements all over. Major changes: qtnfmac * add 802.11ax support in AP mode * enable offload bridging support iwlwifi * support TX/RX antennas reporting mt76 * mt7615 smart carrier sense support * aggregation statistics via debugfs * airtime fairness (ATF) support * mt76x0 OF mac address support ==================== Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c')
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
index a501a1fd5332..8e0d8018208a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pearl_pcie.c
@@ -532,7 +532,7 @@ static int qtnf_tx_queue_ready(struct qtnf_pcie_pearl_state *ps)
return 1;
}
-static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb)
+static int qtnf_pcie_skb_send(struct qtnf_bus *bus, struct sk_buff *skb)
{
struct qtnf_pcie_pearl_state *ps = get_bus_priv(bus);
struct qtnf_pcie_bus_priv *priv = &ps->base;
@@ -608,6 +608,38 @@ tx_done:
return NETDEV_TX_OK;
}
+static int qtnf_pcie_data_tx(struct qtnf_bus *bus, struct sk_buff *skb,
+ unsigned int macid, unsigned int vifid)
+{
+ return qtnf_pcie_skb_send(bus, skb);
+}
+
+static int qtnf_pcie_data_tx_meta(struct qtnf_bus *bus, struct sk_buff *skb,
+ unsigned int macid, unsigned int vifid)
+{
+ struct qtnf_frame_meta_info *meta;
+ int tail_need = sizeof(*meta) - skb_tailroom(skb);
+ int ret;
+
+ if (tail_need > 0 && pskb_expand_head(skb, 0, tail_need, GFP_ATOMIC)) {
+ skb->dev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ meta = skb_put(skb, sizeof(*meta));
+ meta->magic_s = HBM_FRAME_META_MAGIC_PATTERN_S;
+ meta->magic_e = HBM_FRAME_META_MAGIC_PATTERN_E;
+ meta->macid = macid;
+ meta->ifidx = vifid;
+
+ ret = qtnf_pcie_skb_send(bus, skb);
+ if (unlikely(ret == NETDEV_TX_BUSY))
+ __skb_trim(skb, skb->len - sizeof(*meta));
+
+ return ret;
+}
+
static irqreturn_t qtnf_pcie_pearl_interrupt(int irq, void *data)
{
struct qtnf_bus *bus = (struct qtnf_bus *)data;
@@ -796,13 +828,22 @@ static void qtnf_pcie_data_rx_stop(struct qtnf_bus *bus)
qtnf_disable_hdp_irqs(ps);
}
-static const struct qtnf_bus_ops qtnf_pcie_pearl_bus_ops = {
+static void qtnf_pearl_tx_use_meta_info_set(struct qtnf_bus *bus, bool use_meta)
+{
+ if (use_meta)
+ bus->bus_ops->data_tx = qtnf_pcie_data_tx_meta;
+ else
+ bus->bus_ops->data_tx = qtnf_pcie_data_tx;
+}
+
+static struct qtnf_bus_ops qtnf_pcie_pearl_bus_ops = {
/* control path methods */
.control_tx = qtnf_pcie_control_tx,
/* data path methods */
.data_tx = qtnf_pcie_data_tx,
.data_tx_timeout = qtnf_pcie_data_tx_timeout,
+ .data_tx_use_meta_set = qtnf_pearl_tx_use_meta_info_set,
.data_rx_start = qtnf_pcie_data_rx_start,
.data_rx_stop = qtnf_pcie_data_rx_stop,
};
@@ -905,7 +946,7 @@ static int qtnf_ep_fw_send(struct pci_dev *pdev, uint32_t size,
memcpy(pdata, pblk, len);
hdr->crc = cpu_to_le32(~crc32(0, pdata, len));
- ret = qtnf_pcie_data_tx(bus, skb);
+ ret = qtnf_pcie_skb_send(bus, skb);
return (ret == NETDEV_TX_OK) ? len : 0;
}