Commit d0172d5f authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Kalle Valo

wifi: remove obsolete hostap driver

HostAP is an ISA/PCMCIA style 802.11b driver supporting only
wireless extensions, and some custom ioctls (already removed).
Some devices include a legacy PCI bridge but no DMA.

The driver was marked obsolete in 2016 and is highly unlikely
to still have any users.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
parent 6853c70b
......@@ -9553,11 +9553,6 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
F: drivers/iio/pressure/mprls0025pa.c
HOST AP DRIVER
L: linux-wireless@vger.kernel.org
S: Obsolete
F: drivers/net/wireless/intersil/hostap/
HP BIOSCFG DRIVER
M: Jorge Lopez <jorge.lopez2@hp.com>
L: platform-driver-x86@vger.kernel.org
......
......@@ -12,7 +12,6 @@ config WLAN_VENDOR_INTERSIL
if WLAN_VENDOR_INTERSIL
source "drivers/net/wireless/intersil/hostap/Kconfig"
source "drivers/net/wireless/intersil/orinoco/Kconfig"
source "drivers/net/wireless/intersil/p54/Kconfig"
......
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_HOSTAP) += hostap/
obj-$(CONFIG_HERMES) += orinoco/
obj-$(CONFIG_P54_COMMON) += p54/
# SPDX-License-Identifier: GPL-2.0-only
config HOSTAP
tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
select WIRELESS_EXT
select WEXT_SPY
select WEXT_PRIV
select CRYPTO
select CRYPTO_MICHAEL_MIC
select CRC32
select LIB80211
select LIB80211_CRYPT_WEP
select LIB80211_CRYPT_TKIP
select LIB80211_CRYPT_CCMP
help
Shared driver code for IEEE 802.11b wireless cards based on
Intersil Prism2/2.5/3 chipset. This driver supports so called
Host AP mode that allows the card to act as an IEEE 802.11
access point.
See <http://hostap.epitest.fi/> for more information about the
Host AP driver configuration and tools. This site includes
information and tools (hostapd and wpa_supplicant) for WPA/WPA2
support.
This option includes the base Host AP driver code that is shared by
different hardware models. You will also need to enable support for
PLX/PCI/CS version of the driver to actually use the driver.
The driver can be compiled as a module and it will be called
hostap.
config HOSTAP_FIRMWARE
bool "Support downloading firmware images with Host AP driver"
depends on HOSTAP
help
Configure Host AP driver to include support for firmware image
download. This option by itself only enables downloading to the
volatile memory, i.e. the card RAM. This option is required to
support cards that don't have firmware in flash, such as D-Link
DWL-520 rev E and D-Link DWL-650 rev P.
Firmware image downloading needs a user space tool, prism2_srec.
It is available from http://hostap.epitest.fi/.
config HOSTAP_FIRMWARE_NVRAM
bool "Support for non-volatile firmware download"
depends on HOSTAP_FIRMWARE
help
Allow Host AP driver to write firmware images to the non-volatile
card memory, i.e. flash memory that survives power cycling.
Enable this option if you want to be able to change card firmware
permanently.
Firmware image downloading needs a user space tool, prism2_srec.
It is available from http://hostap.epitest.fi/.
config HOSTAP_PLX
tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
depends on PCI && HOSTAP && HAS_IOPORT
help
Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
PCI adaptors.
"Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
driver and its help text includes more information about the Host AP
driver.
The driver can be compiled as a module and will be named
hostap_plx.
config HOSTAP_PCI
tristate "Host AP driver for Prism2.5 PCI adaptors"
depends on PCI && HOSTAP
help
Host AP driver's version for Prism2.5 PCI adaptors.
"Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
driver and its help text includes more information about the Host AP
driver.
The driver can be compiled as a module and will be named
hostap_pci.
config HOSTAP_CS
tristate "Host AP driver for Prism2/2.5/3 PC Cards"
depends on PCMCIA && HOSTAP
help
Host AP driver's version for Prism2/2.5/3 PC Cards.
"Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
driver and its help text includes more information about the Host AP
driver.
The driver can be compiled as a module and will be named
hostap_cs.
# SPDX-License-Identifier: GPL-2.0
hostap-y := hostap_80211_rx.o hostap_80211_tx.o hostap_ap.o hostap_info.o \
hostap_ioctl.o hostap_main.o hostap_proc.o
obj-$(CONFIG_HOSTAP) += hostap.o
obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o
obj-$(CONFIG_HOSTAP_PCI) += hostap_pci.o
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef HOSTAP_H
#define HOSTAP_H
#include <linux/ethtool.h>
#include <linux/kernel.h>
#include "hostap_wlan.h"
#include "hostap_ap.h"
static const long __maybe_unused freq_list[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
#define FREQ_COUNT ARRAY_SIZE(freq_list)
/* hostap.c */
extern struct proc_dir_entry *hostap_proc;
u16 hostap_tx_callback_register(local_info_t *local,
void (*func)(struct sk_buff *, int ok, void *),
void *data);
int hostap_tx_callback_unregister(local_info_t *local, u16 idx);
int hostap_set_word(struct net_device *dev, int rid, u16 val);
int hostap_set_string(struct net_device *dev, int rid, const char *val);
u16 hostap_get_porttype(local_info_t *local);
int hostap_set_encryption(local_info_t *local);
int hostap_set_antsel(local_info_t *local);
int hostap_set_roaming(local_info_t *local);
int hostap_set_auth_algs(local_info_t *local);
void hostap_dump_rx_header(const char *name,
const struct hfa384x_rx_frame *rx);
void hostap_dump_tx_header(const char *name,
const struct hfa384x_tx_frame *tx);
extern const struct header_ops hostap_80211_ops;
int hostap_80211_get_hdrlen(__le16 fc);
struct net_device_stats *hostap_get_stats(struct net_device *dev);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int type);
void hostap_set_multicast_list_queue(struct work_struct *work);
int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked);
int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked);
void hostap_cleanup(local_info_t *local);
void hostap_cleanup_handler(void *data);
struct net_device * hostap_add_interface(struct local_info *local,
int type, int rtnl_locked,
const char *prefix, const char *name);
void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
int remove_from_list);
int prism2_update_comms_qual(struct net_device *dev);
int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
u8 *body, size_t bodylen);
int prism2_sta_deauth(local_info_t *local, u16 reason);
int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked);
int prism2_wds_del(local_info_t *local, u8 *remote_addr,
int rtnl_locked, int do_not_remove);
/* hostap_ap.c */
int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
void ap_control_kickall(struct ap_data *ap);
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
struct lib80211_crypt_data ***crypt);
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
int prism2_ap_translate_scan(struct net_device *dev,
struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
/* hostap_proc.c */
void hostap_init_proc(local_info_t *local);
void hostap_remove_proc(local_info_t *local);
/* hostap_info.c */
void hostap_info_init(local_info_t *local);
void hostap_info_process(local_info_t *local, struct sk_buff *skb);
/* hostap_ioctl.c */
extern const struct iw_handler_def hostap_iw_handler_def;
extern const struct ethtool_ops prism2_ethtool_ops;
int hostap_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd);
#endif /* HOSTAP_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef HOSTAP_80211_H
#define HOSTAP_80211_H
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
struct hostap_ieee80211_mgmt {
__le16 frame_control;
__le16 duration;
u8 da[6];
u8 sa[6];
u8 bssid[6];
__le16 seq_ctrl;
union {
struct {
__le16 auth_alg;
__le16 auth_transaction;
__le16 status_code;
/* possibly followed by Challenge text */
u8 variable[0];
} __packed auth;
struct {
__le16 reason_code;
} __packed deauth;
struct {
__le16 capab_info;
__le16 listen_interval;
/* followed by SSID and Supported rates */
u8 variable[0];
} __packed assoc_req;
struct {
__le16 capab_info;
__le16 status_code;
__le16 aid;
/* followed by Supported rates */
u8 variable[0];
} __packed assoc_resp, reassoc_resp;
struct {
__le16 capab_info;
__le16 listen_interval;
u8 current_ap[6];
/* followed by SSID and Supported rates */
u8 variable[0];
} __packed reassoc_req;
struct {
__le16 reason_code;
} __packed disassoc;
struct {
} __packed probe_req;
struct {
u8 timestamp[8];
__le16 beacon_int;
__le16 capab_info;
/* followed by some of SSID, Supported rates,
* FH Params, DS Params, CF Params, IBSS Params, TIM */
u8 variable[0];
} __packed beacon, probe_resp;
} u;
} __packed;
#define IEEE80211_MGMT_HDR_LEN 24
#define IEEE80211_DATA_HDR3_LEN 24
#define IEEE80211_DATA_HDR4_LEN 30
struct hostap_80211_rx_status {
u32 mac_time;
u8 signal;
u8 noise;
u16 rate; /* in 100 kbps */
};
/* prism2_rx_80211 'type' argument */
enum {
PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
PRISM2_RX_NULLFUNC_ACK
};
int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int type);
void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats);
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats);
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
struct net_device *dev);
netdev_tx_t hostap_mgmt_start_xmit(struct sk_buff *skb,
struct net_device *dev);
netdev_tx_t hostap_master_start_xmit(struct sk_buff *skb,
struct net_device *dev);
#endif /* HOSTAP_80211_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef HOSTAP_AP_H
#define HOSTAP_AP_H
#include "hostap_80211.h"
/* AP data structures for STAs */
/* maximum number of frames to buffer per STA */
#define STA_MAX_TX_BUFFER 32
/* STA flags */
#define WLAN_STA_AUTH BIT(0)
#define WLAN_STA_ASSOC BIT(1)
#define WLAN_STA_PS BIT(2)
#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
* controlling whether STA is authorized to
* send and receive non-IEEE 802.1X frames
*/
#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
#define WLAN_RATE_1M BIT(0)
#define WLAN_RATE_2M BIT(1)
#define WLAN_RATE_5M5 BIT(2)
#define WLAN_RATE_11M BIT(3)
#define WLAN_RATE_COUNT 4
/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
* but some pre-standard IEEE 802.11g products use longer elements. */
#define WLAN_SUPP_RATES_MAX 32
/* Try to increase TX rate after # successfully sent consecutive packets */
#define WLAN_RATE_UPDATE_COUNT 50
/* Decrease TX rate after # consecutive dropped packets */
#define WLAN_RATE_DECREASE_THRESHOLD 2
struct sta_info {
struct list_head list;
struct sta_info *hnext; /* next entry in hash table list */
atomic_t users; /* number of users (do not remove if > 0) */
struct proc_dir_entry *proc;
u8 addr[6];
u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
u32 flags;
u16 capability;
u16 listen_interval; /* or beacon_int for APs */
u8 supported_rates[WLAN_SUPP_RATES_MAX];
unsigned long last_auth;
unsigned long last_assoc;
unsigned long last_rx;
unsigned long last_tx;
unsigned long rx_packets, tx_packets;
unsigned long rx_bytes, tx_bytes;
struct sk_buff_head tx_buf;
/* FIX: timeout buffers with an expiry time somehow derived from
* listen_interval */
s8 last_rx_silence; /* Noise in dBm */
s8 last_rx_signal; /* Signal strength in dBm */
u8 last_rx_rate; /* TX rate in 0.1 Mbps */
u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */
u8 tx_supp_rates; /* bit field of supported TX rates */
u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
*/
u32 tx_since_last_failure;
u32 tx_consecutive_exc;
struct lib80211_crypt_data *crypt;
int ap; /* whether this station is an AP */
local_info_t *local;
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
union {
struct {
char *challenge; /* shared key authentication
* challenge */
} sta;
struct {
int ssid_len;
unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
int channel;
unsigned long last_beacon; /* last RX beacon time */
} ap;
} u;
struct timer_list timer;
enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
};
#define MAX_STA_COUNT 1024
/* Maximum number of AIDs to use for STAs; must be 2007 or lower
* (8802.11 limitation) */
#define MAX_AID_TABLE_SIZE 128
#define STA_HASH_SIZE 256
#define STA_HASH(sta) (sta[5])
/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC
* has passed since last received frame from the station, a nullfunc data
* frame is sent to the station. If this frame is not acknowledged and no other
* frames have been received, the station will be disassociated after
* AP_DISASSOC_DELAY. Similarly, a the station will be deauthenticated after
* AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
* max inactivity timer. */
#define AP_MAX_INACTIVITY_SEC (5 * 60)
#define AP_DISASSOC_DELAY (HZ)
#define AP_DEAUTH_DELAY (HZ)
/* ap_policy: whether to accept frames to/from other APs/IBSS */
typedef enum {
AP_OTHER_AP_SKIP_ALL = 0,
AP_OTHER_AP_SAME_SSID = 1,
AP_OTHER_AP_ALL = 2,
AP_OTHER_AP_EVEN_IBSS = 3
} ap_policy_enum;
#define PRISM2_AUTH_OPEN BIT(0)
#define PRISM2_AUTH_SHARED_KEY BIT(1)
/* MAC address-based restrictions */
struct mac_entry {
struct list_head list;
u8 addr[6];
};
struct mac_restrictions {
enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
unsigned int entries;
struct list_head mac_list;
spinlock_t lock;
};
struct add_sta_proc_data {
u8 addr[ETH_ALEN];
struct add_sta_proc_data *next;
};
typedef enum { WDS_ADD, WDS_DEL } wds_oper_type;
struct wds_oper_data {
wds_oper_type type;
u8 addr[ETH_ALEN];
struct wds_oper_data *next;
};
struct ap_data {
int initialized; /* whether ap_data has been initialized */
local_info_t *local;
int bridge_packets; /* send packet to associated STAs directly to the
* wireless media instead of higher layers in the
* kernel */
unsigned int bridged_unicast; /* number of unicast frames bridged on
* wireless media */
unsigned int bridged_multicast; /* number of non-unicast frames
* bridged on wireless media */
unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped
* because they were to an address that
* was not associated */
int nullfunc_ack; /* use workaround for nullfunc frame ACKs */
spinlock_t sta_table_lock;
int num_sta; /* number of entries in sta_list */
struct list_head sta_list; /* STA info list head */
struct sta_info *sta_hash[STA_HASH_SIZE];
struct proc_dir_entry *proc;
ap_policy_enum ap_policy;
unsigned int max_inactivity;
int autom_ap_wds;
struct mac_restrictions mac_restrictions; /* MAC-based auth */
int last_tx_rate;
struct work_struct add_sta_proc_queue;
struct add_sta_proc_data *add_sta_proc_entries;
struct work_struct wds_oper_queue;
struct wds_oper_data *wds_oper_entries;
u16 tx_callback_idx;
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
/* pointers to STA info; based on allocated AID or NULL if AID free
* AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
* and so on
*/
struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;
/* WEP operations for generating challenges to be used with shared key
* authentication */
struct lib80211_crypto_ops *crypt;
void *crypt_priv;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
};
void hostap_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats);
void hostap_init_data(local_info_t *local);
void hostap_init_ap_proc(local_info_t *local);
void hostap_free_data(struct ap_data *ap);
void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver);
typedef enum {
AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
AP_TX_CONTINUE_NOT_AUTHORIZED
} ap_tx_ret;
struct hostap_tx_data {
struct sk_buff *skb;
int host_encrypt;
struct lib80211_crypt_data *crypt;
void *sta_ptr;
};
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
struct lib80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
int resend);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
#endif /* HOSTAP_AP_H */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef HOSTAP_CONFIG_H
#define HOSTAP_CONFIG_H
/* In the previous versions of Host AP driver, support for user space version
* of IEEE 802.11 management (hostapd) used to be disabled in the default
* configuration. From now on, support for hostapd is always included and it is
* possible to disable kernel driver version of IEEE 802.11 management with a
* separate define, PRISM2_NO_KERNEL_IEEE80211_MGMT. */
/* #define PRISM2_NO_KERNEL_IEEE80211_MGMT */
/* Maximum number of events handler per one interrupt */
#define PRISM2_MAX_INTERRUPT_EVENTS 20
/* Include code for downloading firmware images into volatile RAM. */
#define PRISM2_DOWNLOAD_SUPPORT
/* Allow kernel configuration to enable download support. */
#if !defined(PRISM2_DOWNLOAD_SUPPORT) && defined(CONFIG_HOSTAP_FIRMWARE)
#define PRISM2_DOWNLOAD_SUPPORT
#endif
/* Allow kernel configuration to enable non-volatile download support. */
#ifdef CONFIG_HOSTAP_FIRMWARE_NVRAM
#define PRISM2_NON_VOLATILE_DOWNLOAD
#endif
/* Save low-level I/O for debugging. This should not be enabled in normal use.
*/
/* #define PRISM2_IO_DEBUG */
/* Following defines can be used to remove unneeded parts of the driver, e.g.,
* to limit the size of the kernel module. Definitions can be added here in
* hostap_config.h or they can be added to make command with ccflags-y,
* e.g.,
* 'make pccard ccflags-y="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
*/
/* Do not include debug messages into the driver */
/* #define PRISM2_NO_DEBUG */
/* Do not include /proc/net/prism2/wlan#/{registers,debug} */
/* #define PRISM2_NO_PROCFS_DEBUG */
/* Do not include station functionality (i.e., allow only Master (Host AP) mode
*/
/* #define PRISM2_NO_STATION_MODES */
#endif /* HOSTAP_CONFIG_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment