All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kalle Valo <kvalo@codeaurora.org>
To: linux-wireless@vger.kernel.org
Cc: ath11k@lists.infradead.org, devicetree@vger.kernel.org
Subject: [PATCH v3 07/49] ath11k: add ce.h
Date: Fri, 15 Nov 2019 11:28:31 +0200	[thread overview]
Message-ID: <1573810153-29623-8-git-send-email-kvalo@codeaurora.org> (raw)
In-Reply-To: <1573810153-29623-1-git-send-email-kvalo@codeaurora.org>

(patches split for easier review, see the cover letter for more)

Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/ce.h | 178 +++++++++++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h
new file mode 100644
index 000000000000..6174eac84410
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/ce.h
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef ATH11K_CE_H
+#define ATH11K_CE_H
+
+#define CE_COUNT 12
+
+/* Byte swap data words */
+#define CE_ATTR_BYTE_SWAP_DATA 2
+
+/* no interrupt on copy completion */
+#define CE_ATTR_DIS_INTR		8
+
+/* Host software's Copy Engine configuration. */
+#ifdef __BIG_ENDIAN
+#define CE_ATTR_FLAGS CE_ATTR_BYTE_SWAP_DATA
+#else
+#define CE_ATTR_FLAGS 0
+#endif
+
+/* Threshold to poll for tx completion in case of Interrupt disabled CE's */
+#define ATH11K_CE_USAGE_THRESHOLD 32
+
+void ath11k_ce_byte_swap(void *mem, u32 len);
+
+/*
+ * Directions for interconnect pipe configuration.
+ * These definitions may be used during configuration and are shared
+ * between Host and Target.
+ *
+ * Pipe Directions are relative to the Host, so PIPEDIR_IN means
+ * "coming IN over air through Target to Host" as with a WiFi Rx operation.
+ * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
+ * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
+ * Target since things that are "PIPEDIR_OUT" are coming IN to the Target
+ * over the interconnect.
+ */
+#define PIPEDIR_NONE		0
+#define PIPEDIR_IN		1 /* Target-->Host, WiFi Rx direction */
+#define PIPEDIR_OUT		2 /* Host->Target, WiFi Tx direction */
+#define PIPEDIR_INOUT		3 /* bidirectional */
+#define PIPEDIR_INOUT_H2H	4 /* bidirectional, host to host */
+
+/* CE address/mask */
+#define CE_HOST_IE_ADDRESS	0x00A1803C
+#define CE_HOST_IE_2_ADDRESS	0x00A18040
+#define CE_HOST_IE_3_ADDRESS	CE_HOST_IE_ADDRESS
+
+#define CE_HOST_IE_3_SHIFT	0xC
+
+#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
+
+#define ATH11K_CE_RX_POST_RETRY_JIFFIES 50
+
+struct ath11k_base;
+
+/* Establish a mapping between a service/direction and a pipe. */
+struct service_to_pipe {
+	__le32 service_id;
+	__le32 pipedir;
+	__le32 pipenum;
+};
+
+/*
+ * Configuration information for a Copy Engine pipe.
+ * Passed from Host to Target during startup (one per CE).
+ *
+ * NOTE: Structure is shared between Host software and Target firmware!
+ */
+struct ce_pipe_config {
+	__le32 pipenum;
+	__le32 pipedir;
+	__le32 nentries;
+	__le32 nbytes_max;
+	__le32 flags;
+	__le32 reserved;
+};
+
+struct ce_attr {
+	/* CE_ATTR_* values */
+	unsigned int flags;
+
+	/* #entries in source ring - Must be a power of 2 */
+	unsigned int src_nentries;
+
+	/*
+	 * Max source send size for this CE.
+	 * This is also the minimum size of a destination buffer.
+	 */
+	unsigned int src_sz_max;
+
+	/* #entries in destination ring - Must be a power of 2 */
+	unsigned int dest_nentries;
+
+	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
+};
+
+#define CE_DESC_RING_ALIGN 8
+
+struct ath11k_ce_ring {
+	/* Number of entries in this ring; must be power of 2 */
+	unsigned int nentries;
+	unsigned int nentries_mask;
+
+	/* For dest ring, this is the next index to be processed
+	 * by software after it was/is received into.
+	 *
+	 * For src ring, this is the last descriptor that was sent
+	 * and completion processed by software.
+	 *
+	 * Regardless of src or dest ring, this is an invariant
+	 * (modulo ring size):
+	 *     write index >= read index >= sw_index
+	 */
+	unsigned int sw_index;
+	/* cached copy */
+	unsigned int write_index;
+
+	/* Start of DMA-coherent area reserved for descriptors */
+	/* Host address space */
+	void *base_addr_owner_space_unaligned;
+	/* CE address space */
+	u32 base_addr_ce_space_unaligned;
+
+	/* Actual start of descriptors.
+	 * Aligned to descriptor-size boundary.
+	 * Points into reserved DMA-coherent area, above.
+	 */
+	/* Host address space */
+	void *base_addr_owner_space;
+
+	/* CE address space */
+	u32 base_addr_ce_space;
+
+	/* HAL ring id */
+	u32 hal_ring_id;
+
+	/* keep last */
+	struct sk_buff *skb[0];
+};
+
+struct ath11k_ce_pipe {
+	struct ath11k_base *ab;
+	u16 pipe_num;
+	unsigned int attr_flags;
+	unsigned int buf_sz;
+	unsigned int rx_buf_needed;
+
+	void (*send_cb)(struct ath11k_ce_pipe *);
+	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
+
+	struct tasklet_struct intr_tq;
+	struct ath11k_ce_ring *src_ring;
+	struct ath11k_ce_ring *dest_ring;
+	struct ath11k_ce_ring *status_ring;
+};
+
+struct ath11k_ce {
+	struct ath11k_ce_pipe ce_pipe[CE_COUNT];
+	/* Protects rings of all ce pipes */
+	spinlock_t ce_lock;
+};
+
+void ath11k_ce_cleanup_pipes(struct ath11k_base *ab);
+void ath11k_ce_rx_replenish_retry(struct timer_list *t);
+void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id);
+int ath11k_ce_send(struct ath11k_base *ab, struct sk_buff *skb, u8 pipe_id,
+		   u16 transfer_id);
+void ath11k_ce_rx_post_buf(struct ath11k_base *ab);
+int ath11k_ce_init_pipes(struct ath11k_base *ab);
+int ath11k_ce_alloc_pipes(struct ath11k_base *ab);
+void ath11k_ce_free_pipes(struct ath11k_base *ab);
+int ath11k_ce_get_attr_flags(int ce_id);
+void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id);
+#endif


WARNING: multiple messages have this Message-ID (diff)
From: Kalle Valo <kvalo@codeaurora.org>
To: linux-wireless@vger.kernel.org
Cc: devicetree@vger.kernel.org, ath11k@lists.infradead.org
Subject: [PATCH v3 07/49] ath11k: add ce.h
Date: Fri, 15 Nov 2019 11:28:31 +0200	[thread overview]
Message-ID: <1573810153-29623-8-git-send-email-kvalo@codeaurora.org> (raw)
In-Reply-To: <1573810153-29623-1-git-send-email-kvalo@codeaurora.org>

(patches split for easier review, see the cover letter for more)

Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/ce.h | 178 +++++++++++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h
new file mode 100644
index 000000000000..6174eac84410
--- /dev/null
+++ b/drivers/net/wireless/ath/ath11k/ce.h
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef ATH11K_CE_H
+#define ATH11K_CE_H
+
+#define CE_COUNT 12
+
+/* Byte swap data words */
+#define CE_ATTR_BYTE_SWAP_DATA 2
+
+/* no interrupt on copy completion */
+#define CE_ATTR_DIS_INTR		8
+
+/* Host software's Copy Engine configuration. */
+#ifdef __BIG_ENDIAN
+#define CE_ATTR_FLAGS CE_ATTR_BYTE_SWAP_DATA
+#else
+#define CE_ATTR_FLAGS 0
+#endif
+
+/* Threshold to poll for tx completion in case of Interrupt disabled CE's */
+#define ATH11K_CE_USAGE_THRESHOLD 32
+
+void ath11k_ce_byte_swap(void *mem, u32 len);
+
+/*
+ * Directions for interconnect pipe configuration.
+ * These definitions may be used during configuration and are shared
+ * between Host and Target.
+ *
+ * Pipe Directions are relative to the Host, so PIPEDIR_IN means
+ * "coming IN over air through Target to Host" as with a WiFi Rx operation.
+ * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
+ * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
+ * Target since things that are "PIPEDIR_OUT" are coming IN to the Target
+ * over the interconnect.
+ */
+#define PIPEDIR_NONE		0
+#define PIPEDIR_IN		1 /* Target-->Host, WiFi Rx direction */
+#define PIPEDIR_OUT		2 /* Host->Target, WiFi Tx direction */
+#define PIPEDIR_INOUT		3 /* bidirectional */
+#define PIPEDIR_INOUT_H2H	4 /* bidirectional, host to host */
+
+/* CE address/mask */
+#define CE_HOST_IE_ADDRESS	0x00A1803C
+#define CE_HOST_IE_2_ADDRESS	0x00A18040
+#define CE_HOST_IE_3_ADDRESS	CE_HOST_IE_ADDRESS
+
+#define CE_HOST_IE_3_SHIFT	0xC
+
+#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
+
+#define ATH11K_CE_RX_POST_RETRY_JIFFIES 50
+
+struct ath11k_base;
+
+/* Establish a mapping between a service/direction and a pipe. */
+struct service_to_pipe {
+	__le32 service_id;
+	__le32 pipedir;
+	__le32 pipenum;
+};
+
+/*
+ * Configuration information for a Copy Engine pipe.
+ * Passed from Host to Target during startup (one per CE).
+ *
+ * NOTE: Structure is shared between Host software and Target firmware!
+ */
+struct ce_pipe_config {
+	__le32 pipenum;
+	__le32 pipedir;
+	__le32 nentries;
+	__le32 nbytes_max;
+	__le32 flags;
+	__le32 reserved;
+};
+
+struct ce_attr {
+	/* CE_ATTR_* values */
+	unsigned int flags;
+
+	/* #entries in source ring - Must be a power of 2 */
+	unsigned int src_nentries;
+
+	/*
+	 * Max source send size for this CE.
+	 * This is also the minimum size of a destination buffer.
+	 */
+	unsigned int src_sz_max;
+
+	/* #entries in destination ring - Must be a power of 2 */
+	unsigned int dest_nentries;
+
+	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
+};
+
+#define CE_DESC_RING_ALIGN 8
+
+struct ath11k_ce_ring {
+	/* Number of entries in this ring; must be power of 2 */
+	unsigned int nentries;
+	unsigned int nentries_mask;
+
+	/* For dest ring, this is the next index to be processed
+	 * by software after it was/is received into.
+	 *
+	 * For src ring, this is the last descriptor that was sent
+	 * and completion processed by software.
+	 *
+	 * Regardless of src or dest ring, this is an invariant
+	 * (modulo ring size):
+	 *     write index >= read index >= sw_index
+	 */
+	unsigned int sw_index;
+	/* cached copy */
+	unsigned int write_index;
+
+	/* Start of DMA-coherent area reserved for descriptors */
+	/* Host address space */
+	void *base_addr_owner_space_unaligned;
+	/* CE address space */
+	u32 base_addr_ce_space_unaligned;
+
+	/* Actual start of descriptors.
+	 * Aligned to descriptor-size boundary.
+	 * Points into reserved DMA-coherent area, above.
+	 */
+	/* Host address space */
+	void *base_addr_owner_space;
+
+	/* CE address space */
+	u32 base_addr_ce_space;
+
+	/* HAL ring id */
+	u32 hal_ring_id;
+
+	/* keep last */
+	struct sk_buff *skb[0];
+};
+
+struct ath11k_ce_pipe {
+	struct ath11k_base *ab;
+	u16 pipe_num;
+	unsigned int attr_flags;
+	unsigned int buf_sz;
+	unsigned int rx_buf_needed;
+
+	void (*send_cb)(struct ath11k_ce_pipe *);
+	void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
+
+	struct tasklet_struct intr_tq;
+	struct ath11k_ce_ring *src_ring;
+	struct ath11k_ce_ring *dest_ring;
+	struct ath11k_ce_ring *status_ring;
+};
+
+struct ath11k_ce {
+	struct ath11k_ce_pipe ce_pipe[CE_COUNT];
+	/* Protects rings of all ce pipes */
+	spinlock_t ce_lock;
+};
+
+void ath11k_ce_cleanup_pipes(struct ath11k_base *ab);
+void ath11k_ce_rx_replenish_retry(struct timer_list *t);
+void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id);
+int ath11k_ce_send(struct ath11k_base *ab, struct sk_buff *skb, u8 pipe_id,
+		   u16 transfer_id);
+void ath11k_ce_rx_post_buf(struct ath11k_base *ab);
+int ath11k_ce_init_pipes(struct ath11k_base *ab);
+int ath11k_ce_alloc_pipes(struct ath11k_base *ab);
+void ath11k_ce_free_pipes(struct ath11k_base *ab);
+int ath11k_ce_get_attr_flags(int ce_id);
+void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id);
+#endif


_______________________________________________
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

  parent reply	other threads:[~2019-11-15  9:29 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-15  9:28 [PATCH v3 00/49] ath11k: driver for Qualcomm IEEE 802.11ax devices Kalle Valo
2019-11-15  9:28 ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 01/49] dt: bindings: net: add qcom,ath11k.yaml Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-23  0:23   ` Rob Herring
2019-11-23  0:23     ` Rob Herring
2019-11-15  9:28 ` [PATCH v3 02/49] ath11k: add Kconfig Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 03/49] ath11k: add Makefile Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 04/49] ath11k: add ahb.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 05/49] ath11k: add ahb.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 06/49] ath11k: add ce.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` Kalle Valo [this message]
2019-11-15  9:28   ` [PATCH v3 07/49] ath11k: add ce.h Kalle Valo
2019-11-15  9:28 ` [PATCH v3 08/49] ath11k: add core.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 09/49] ath11k: add core.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 10/49] ath11k: add debug.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 11/49] ath11k: add debug.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 12/49] ath11k: add debug_htt_stats.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 13/49] ath11k: add debug_htt_stats.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 14/49] ath11k: add debugfs_sta.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 15/49] ath11k: add dp.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 16/49] ath11k: add dp.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 17/49] ath11k: add dp_rx.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 18/49] ath11k: add dp_rx.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 19/49] ath11k: add dp_tx.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 20/49] ath11k: add dp_tx.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 21/49] ath11k: add hal.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 22/49] ath11k: add hal.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 23/49] ath11k: add hal_desc.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 24/49] ath11k: add hal_rx.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 25/49] ath11k: add hal_rx.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 26/49] ath11k: add hal_tx.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 27/49] ath11k: add hal_tx.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 28/49] ath11k: add htc.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 29/49] ath11k: add htc.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 30/49] ath11k: add hw.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 31/49] ath11k: add mac.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 32/49] ath11k: add mac.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 33/49] ath11k: add peer.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 34/49] ath11k: add peer.h Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:28 ` [PATCH v3 35/49] ath11k: add qmi.c Kalle Valo
2019-11-15  9:28   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 36/49] ath11k: add qmi.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 37/49] ath11k: add reg.c Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 38/49] ath11k: add reg.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 39/49] ath11k: add rx_desc.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 40/49] ath11k: add testmode.c Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 41/49] ath11k: add testmode.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 42/49] ath11k: add testmode_i.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 43/49] ath11k: add trace.c Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 44/49] ath11k: add trace.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 45/49] ath11k: add wmi.c Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 46/49] ath11k: add wmi.h Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 47/49] ath: add ath11k to Makefile Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 48/49] ath: add ath11k to Kconfig Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-15  9:29 ` [PATCH v3 49/49] MAINTAINERS: add ath11k Kalle Valo
2019-11-15  9:29   ` Kalle Valo
2019-11-23  8:26 ` [PATCH v3 00/49] ath11k: driver for Qualcomm IEEE 802.11ax devices Kalle Valo
2019-11-25 12:31   ` Kalle Valo
2019-11-25 12:31   ` Kalle Valo
2019-11-23  8:26 ` Kalle Valo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1573810153-29623-8-git-send-email-kvalo@codeaurora.org \
    --to=kvalo@codeaurora.org \
    --cc=ath11k@lists.infradead.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.