From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
To: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>,
<intel-wired-lan@lists.osuosl.org>
Cc: maciej.fijalkowski@intel.com, mateusz.polchlopek@intel.com,
nex.sw.ncis.osdt.itp.upstreaming@intel.com,
netdev@vger.kernel.org, jiri@nvidia.com, michal.kubiak@intel.com,
pio.raczynski@gmail.com, sridhar.samudrala@intel.com,
jacob.e.keller@intel.com, wojciech.drewek@intel.com,
Piotr Raczynski <piotr.raczynski@intel.com>
Subject: Re: [Intel-wired-lan] [iwl-next v3 5/7] ice: base subfunction aux driver
Date: Fri, 12 Apr 2024 13:44:45 +0200 [thread overview]
Message-ID: <da5f3048-e90b-4e34-be23-602c8a9edeb2@intel.com> (raw)
In-Reply-To: <20240412063053.339795-6-michal.swiatkowski@linux.intel.com>
On 4/12/24 08:30, Michal Swiatkowski wrote:
> From: Piotr Raczynski <piotr.raczynski@intel.com>
>
> Implement subfunction driver. It is probe when subfunction port is
> activated.
>
> VSI is already created. During the probe VSI is being configured.
> MAC unicast and broadcast filter is added to allow traffic to pass.
>
> Signed-off-by: Piotr Raczynski <piotr.raczynski@intel.com>
> Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
> ---
> drivers/net/ethernet/intel/ice/Makefile | 1 +
> drivers/net/ethernet/intel/ice/ice_main.c | 10 ++
> drivers/net/ethernet/intel/ice/ice_sf_eth.c | 130 ++++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_sf_eth.h | 9 ++
> 4 files changed, 150 insertions(+)
> create mode 100644 drivers/net/ethernet/intel/ice/ice_sf_eth.c
>
> diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile
> index 03500e28ac99..4d987f5dcdc1 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -31,6 +31,7 @@ ice-y := ice_main.o \
> ice_idc.o \
> devlink/devlink.o \
> devlink/devlink_port.o \
> + ice_sf_eth.o \
> ice_ddp.o \
> ice_fw_update.o \
> ice_lag.o \
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
> index 29552598ddb6..f55e3340b608 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -15,6 +15,7 @@
> #include "ice_dcb_nl.h"
> #include "devlink/devlink.h"
> #include "devlink/devlink_port.h"
> +#include "ice_sf_eth.h"
> #include "ice_hwmon.h"
> /* Including ice_trace.h with CREATE_TRACE_POINTS defined will generate the
> * ice tracepoint functions. This must be done exactly once across the
> @@ -5857,8 +5858,16 @@ static int __init ice_module_init(void)
> goto err_dest_lag_wq;
> }
>
> + status = ice_sf_driver_register();
> + if (status) {
> + pr_err("Failed to register SF driver, err %d\n", status);
> + goto err_sf_driver;
> + }
> +
> return 0;
>
> +err_sf_driver:
> + pci_unregister_driver(&ice_driver);
> err_dest_lag_wq:
> destroy_workqueue(ice_lag_wq);
> ice_debugfs_exit();
> @@ -5876,6 +5885,7 @@ module_init(ice_module_init);
> */
> static void __exit ice_module_exit(void)
> {
> + ice_sf_driver_unregister();
> pci_unregister_driver(&ice_driver);
> ice_debugfs_exit();
> destroy_workqueue(ice_wq);
> diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.c b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
> new file mode 100644
> index 000000000000..70f7cbe6c609
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
> @@ -0,0 +1,130 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2024, Intel Corporation. */
> +#include "ice.h"
> +#include "ice_lib.h"
> +#include "ice_fltr.h"
> +#include "ice_sf_eth.h"
> +#include "devlink/devlink_port.h"
> +#include "devlink/devlink.h"
> +
> +/**
> + * ice_sf_dev_probe - subfunction driver probe function
> + * @adev: pointer to the auxiliary device
> + * @id: pointer to the auxiliary_device id
> + *
> + * Configure VSI and netdev resources for the subfunction device.
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +static int ice_sf_dev_probe(struct auxiliary_device *adev,
> + const struct auxiliary_device_id *id)
> +{
> + struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
> + struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
> + struct ice_vsi_cfg_params params = {};
> + struct ice_vsi *vsi = dyn_port->vsi;
> + struct ice_pf *pf = dyn_port->pf;
> + struct device *dev = &adev->dev;
> + struct ice_sf_priv *priv;
> + int err;
> +
> + params.type = ICE_VSI_SF;
> + params.pi = pf->hw.port_info;
> + params.flags = ICE_VSI_FLAG_INIT;
> +
> + priv = ice_allocate_sf(&adev->dev);
> + if (!priv) {
> + dev_err(dev, "Subfunction devlink alloc failed");
> + return -ENOMEM;
> + }
> +
> + priv->dev = sf_dev;
> + sf_dev->priv = priv;
> +
> + devlink_register(priv_to_devlink(priv));
> +
> + err = ice_vsi_cfg(vsi, ¶ms);
> + if (err) {
> + dev_err(dev, "Subfunction vsi config failed");
> + return err;
> + }
> +
> + err = ice_devlink_create_sf_dev_port(sf_dev);
> + if (err) {
> + dev_err(dev, "Cannot add ice virtual devlink port for subfunction");
> + goto err_vsi_decfg;
> + }
> +
> + err = ice_fltr_add_mac_and_broadcast(vsi, vsi->netdev->dev_addr,
> + ICE_FWD_TO_VSI);
> + if (err) {
> + dev_err(dev, "can't add MAC filters %pM for VSI %d\n",
> + vsi->netdev->dev_addr, vsi->idx);
> + goto err_devlink_destroy;
> + }
> +
> + ice_napi_add(vsi);
> +
> + return err;
> +
> +err_devlink_destroy:
> + ice_devlink_destroy_sf_dev_port(sf_dev);
> +err_vsi_decfg:
> + ice_vsi_decfg(vsi);
> + return err;
> +}
> +
> +/**
> + * ice_sf_dev_remove - subfunction driver remove function
> + * @adev: pointer to the auxiliary device
> + *
> + * Deinitalize VSI and netdev resources for the subfunction device.
> + */
> +static void ice_sf_dev_remove(struct auxiliary_device *adev)
> +{
> + struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
> + struct devlink *devlink = priv_to_devlink(sf_dev->priv);
RCT
> + struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
> + struct ice_vsi *vsi = dyn_port->vsi;
> +
> + ice_vsi_close(vsi);
> +
> + ice_devlink_destroy_sf_dev_port(sf_dev);
> + devlink_unregister(devlink);
> + devlink_free(devlink);
> + ice_vsi_decfg(vsi);
> +}
> +
> +static const struct auxiliary_device_id ice_sf_dev_id_table[] = {
> + { .name = "ice.sf", },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(auxiliary, ice_sf_dev_id_table);
> +
> +static struct auxiliary_driver ice_sf_driver = {
> + .name = "sf",
> + .probe = ice_sf_dev_probe,
> + .remove = ice_sf_dev_remove,
> + .id_table = ice_sf_dev_id_table
> +};
> +
> +/**
> + * ice_sf_driver_register - Register new auxiliary subfunction driver
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +int ice_sf_driver_register(void)
> +{
> + return auxiliary_driver_register(&ice_sf_driver);
> +}
> +
> +/**
> + * ice_sf_driver_unregister - Unregister new auxiliary subfunction driver
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +void ice_sf_driver_unregister(void)
> +{
> + auxiliary_driver_unregister(&ice_sf_driver);
> +}
> diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.h b/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> index a08f8b2bceef..e972c50f96c9 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> +++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> @@ -18,4 +18,13 @@ struct ice_sf_priv {
> struct devlink_port devlink_port;
> };
>
> +static inline struct
> +ice_sf_dev *ice_adev_to_sf_dev(struct auxiliary_device *adev)
> +{
> + return container_of(adev, struct ice_sf_dev, adev);
> +}
> +
> +int ice_sf_driver_register(void);
> +void ice_sf_driver_unregister(void);
> +
> #endif /* _ICE_SF_ETH_H_ */
WARNING: multiple messages have this Message-ID (diff)
From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
To: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>,
<intel-wired-lan@lists.osuosl.org>
Cc: <netdev@vger.kernel.org>, <jacob.e.keller@intel.com>,
<michal.kubiak@intel.com>, <maciej.fijalkowski@intel.com>,
<sridhar.samudrala@intel.com>, <wojciech.drewek@intel.com>,
<pio.raczynski@gmail.com>, <jiri@nvidia.com>,
<nex.sw.ncis.osdt.itp.upstreaming@intel.com>,
<mateusz.polchlopek@intel.com>,
Piotr Raczynski <piotr.raczynski@intel.com>
Subject: Re: [iwl-next v3 5/7] ice: base subfunction aux driver
Date: Fri, 12 Apr 2024 13:44:45 +0200 [thread overview]
Message-ID: <da5f3048-e90b-4e34-be23-602c8a9edeb2@intel.com> (raw)
In-Reply-To: <20240412063053.339795-6-michal.swiatkowski@linux.intel.com>
On 4/12/24 08:30, Michal Swiatkowski wrote:
> From: Piotr Raczynski <piotr.raczynski@intel.com>
>
> Implement subfunction driver. It is probe when subfunction port is
> activated.
>
> VSI is already created. During the probe VSI is being configured.
> MAC unicast and broadcast filter is added to allow traffic to pass.
>
> Signed-off-by: Piotr Raczynski <piotr.raczynski@intel.com>
> Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
> ---
> drivers/net/ethernet/intel/ice/Makefile | 1 +
> drivers/net/ethernet/intel/ice/ice_main.c | 10 ++
> drivers/net/ethernet/intel/ice/ice_sf_eth.c | 130 ++++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_sf_eth.h | 9 ++
> 4 files changed, 150 insertions(+)
> create mode 100644 drivers/net/ethernet/intel/ice/ice_sf_eth.c
>
> diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile
> index 03500e28ac99..4d987f5dcdc1 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -31,6 +31,7 @@ ice-y := ice_main.o \
> ice_idc.o \
> devlink/devlink.o \
> devlink/devlink_port.o \
> + ice_sf_eth.o \
> ice_ddp.o \
> ice_fw_update.o \
> ice_lag.o \
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
> index 29552598ddb6..f55e3340b608 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -15,6 +15,7 @@
> #include "ice_dcb_nl.h"
> #include "devlink/devlink.h"
> #include "devlink/devlink_port.h"
> +#include "ice_sf_eth.h"
> #include "ice_hwmon.h"
> /* Including ice_trace.h with CREATE_TRACE_POINTS defined will generate the
> * ice tracepoint functions. This must be done exactly once across the
> @@ -5857,8 +5858,16 @@ static int __init ice_module_init(void)
> goto err_dest_lag_wq;
> }
>
> + status = ice_sf_driver_register();
> + if (status) {
> + pr_err("Failed to register SF driver, err %d\n", status);
> + goto err_sf_driver;
> + }
> +
> return 0;
>
> +err_sf_driver:
> + pci_unregister_driver(&ice_driver);
> err_dest_lag_wq:
> destroy_workqueue(ice_lag_wq);
> ice_debugfs_exit();
> @@ -5876,6 +5885,7 @@ module_init(ice_module_init);
> */
> static void __exit ice_module_exit(void)
> {
> + ice_sf_driver_unregister();
> pci_unregister_driver(&ice_driver);
> ice_debugfs_exit();
> destroy_workqueue(ice_wq);
> diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.c b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
> new file mode 100644
> index 000000000000..70f7cbe6c609
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
> @@ -0,0 +1,130 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2024, Intel Corporation. */
> +#include "ice.h"
> +#include "ice_lib.h"
> +#include "ice_fltr.h"
> +#include "ice_sf_eth.h"
> +#include "devlink/devlink_port.h"
> +#include "devlink/devlink.h"
> +
> +/**
> + * ice_sf_dev_probe - subfunction driver probe function
> + * @adev: pointer to the auxiliary device
> + * @id: pointer to the auxiliary_device id
> + *
> + * Configure VSI and netdev resources for the subfunction device.
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +static int ice_sf_dev_probe(struct auxiliary_device *adev,
> + const struct auxiliary_device_id *id)
> +{
> + struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
> + struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
> + struct ice_vsi_cfg_params params = {};
> + struct ice_vsi *vsi = dyn_port->vsi;
> + struct ice_pf *pf = dyn_port->pf;
> + struct device *dev = &adev->dev;
> + struct ice_sf_priv *priv;
> + int err;
> +
> + params.type = ICE_VSI_SF;
> + params.pi = pf->hw.port_info;
> + params.flags = ICE_VSI_FLAG_INIT;
> +
> + priv = ice_allocate_sf(&adev->dev);
> + if (!priv) {
> + dev_err(dev, "Subfunction devlink alloc failed");
> + return -ENOMEM;
> + }
> +
> + priv->dev = sf_dev;
> + sf_dev->priv = priv;
> +
> + devlink_register(priv_to_devlink(priv));
> +
> + err = ice_vsi_cfg(vsi, ¶ms);
> + if (err) {
> + dev_err(dev, "Subfunction vsi config failed");
> + return err;
> + }
> +
> + err = ice_devlink_create_sf_dev_port(sf_dev);
> + if (err) {
> + dev_err(dev, "Cannot add ice virtual devlink port for subfunction");
> + goto err_vsi_decfg;
> + }
> +
> + err = ice_fltr_add_mac_and_broadcast(vsi, vsi->netdev->dev_addr,
> + ICE_FWD_TO_VSI);
> + if (err) {
> + dev_err(dev, "can't add MAC filters %pM for VSI %d\n",
> + vsi->netdev->dev_addr, vsi->idx);
> + goto err_devlink_destroy;
> + }
> +
> + ice_napi_add(vsi);
> +
> + return err;
> +
> +err_devlink_destroy:
> + ice_devlink_destroy_sf_dev_port(sf_dev);
> +err_vsi_decfg:
> + ice_vsi_decfg(vsi);
> + return err;
> +}
> +
> +/**
> + * ice_sf_dev_remove - subfunction driver remove function
> + * @adev: pointer to the auxiliary device
> + *
> + * Deinitalize VSI and netdev resources for the subfunction device.
> + */
> +static void ice_sf_dev_remove(struct auxiliary_device *adev)
> +{
> + struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
> + struct devlink *devlink = priv_to_devlink(sf_dev->priv);
RCT
> + struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
> + struct ice_vsi *vsi = dyn_port->vsi;
> +
> + ice_vsi_close(vsi);
> +
> + ice_devlink_destroy_sf_dev_port(sf_dev);
> + devlink_unregister(devlink);
> + devlink_free(devlink);
> + ice_vsi_decfg(vsi);
> +}
> +
> +static const struct auxiliary_device_id ice_sf_dev_id_table[] = {
> + { .name = "ice.sf", },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(auxiliary, ice_sf_dev_id_table);
> +
> +static struct auxiliary_driver ice_sf_driver = {
> + .name = "sf",
> + .probe = ice_sf_dev_probe,
> + .remove = ice_sf_dev_remove,
> + .id_table = ice_sf_dev_id_table
> +};
> +
> +/**
> + * ice_sf_driver_register - Register new auxiliary subfunction driver
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +int ice_sf_driver_register(void)
> +{
> + return auxiliary_driver_register(&ice_sf_driver);
> +}
> +
> +/**
> + * ice_sf_driver_unregister - Unregister new auxiliary subfunction driver
> + *
> + * Return: zero on success or an error code on failure.
> + */
> +void ice_sf_driver_unregister(void)
> +{
> + auxiliary_driver_unregister(&ice_sf_driver);
> +}
> diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.h b/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> index a08f8b2bceef..e972c50f96c9 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> +++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.h
> @@ -18,4 +18,13 @@ struct ice_sf_priv {
> struct devlink_port devlink_port;
> };
>
> +static inline struct
> +ice_sf_dev *ice_adev_to_sf_dev(struct auxiliary_device *adev)
> +{
> + return container_of(adev, struct ice_sf_dev, adev);
> +}
> +
> +int ice_sf_driver_register(void);
> +void ice_sf_driver_unregister(void);
> +
> #endif /* _ICE_SF_ETH_H_ */
next prev parent reply other threads:[~2024-04-12 11:45 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-12 6:30 [Intel-wired-lan] [iwl-next v3 0/7] ice: support devlink subfunction Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 1/7] ice: add new VSI type for subfunctions Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 2/7] ice: export ice ndo_ops functions Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 3/7] ice: add basic devlink subfunctions support Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 7:12 ` [Intel-wired-lan] " Jiri Pirko
2024-04-12 7:12 ` Jiri Pirko
2024-04-15 8:39 ` [Intel-wired-lan] " Michal Swiatkowski
2024-04-15 8:39 ` Michal Swiatkowski
2024-04-15 9:10 ` [Intel-wired-lan] " Jiri Pirko
2024-04-15 9:10 ` Jiri Pirko
2024-04-16 5:14 ` [Intel-wired-lan] " Michal Swiatkowski
2024-04-16 5:14 ` Michal Swiatkowski
2024-04-16 6:16 ` [Intel-wired-lan] " Michal Swiatkowski
2024-04-16 6:16 ` Michal Swiatkowski
2024-04-16 12:09 ` Jiri Pirko
2024-04-16 12:09 ` Jiri Pirko
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 4/7] ice: allocate devlink for subfunction Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 7:24 ` [Intel-wired-lan] " Jiri Pirko
2024-04-12 7:24 ` Jiri Pirko
2024-04-15 8:40 ` [Intel-wired-lan] " Michal Swiatkowski
2024-04-15 8:40 ` Michal Swiatkowski
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 5/7] ice: base subfunction aux driver Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 7:20 ` [Intel-wired-lan] " Jiri Pirko
2024-04-12 7:20 ` Jiri Pirko
2024-04-12 11:44 ` Przemek Kitszel [this message]
2024-04-12 11:44 ` Przemek Kitszel
2024-04-15 8:29 ` [Intel-wired-lan] " Michal Swiatkowski
2024-04-15 8:29 ` Michal Swiatkowski
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 6/7] ice: implement netdev for subfunction Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
2024-04-12 7:21 ` [Intel-wired-lan] " Jiri Pirko
2024-04-12 7:21 ` Jiri Pirko
2024-04-12 6:30 ` [Intel-wired-lan] [iwl-next v3 7/7] ice: allow to activate and deactivate subfunction Michal Swiatkowski
2024-04-12 6:30 ` Michal Swiatkowski
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=da5f3048-e90b-4e34-be23-602c8a9edeb2@intel.com \
--to=przemyslaw.kitszel@intel.com \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=jacob.e.keller@intel.com \
--cc=jiri@nvidia.com \
--cc=maciej.fijalkowski@intel.com \
--cc=mateusz.polchlopek@intel.com \
--cc=michal.kubiak@intel.com \
--cc=michal.swiatkowski@linux.intel.com \
--cc=netdev@vger.kernel.org \
--cc=nex.sw.ncis.osdt.itp.upstreaming@intel.com \
--cc=pio.raczynski@gmail.com \
--cc=piotr.raczynski@intel.com \
--cc=sridhar.samudrala@intel.com \
--cc=wojciech.drewek@intel.com \
/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.