Commit 79d2232f authored by Rafał Miłecki's avatar Rafał Miłecki Committed by John W. Linville

b43: bus: abstract board info

Signed-off-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c244e08c
...@@ -74,6 +74,10 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) ...@@ -74,6 +74,10 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
dev->dma_dev = sdev->dma_dev; dev->dma_dev = sdev->dma_dev;
dev->irq = sdev->irq; dev->irq = sdev->irq;
dev->board_vendor = sdev->bus->boardinfo.vendor;
dev->board_type = sdev->bus->boardinfo.type;
dev->board_rev = sdev->bus->boardinfo.rev;
dev->chip_id = sdev->bus->chip_id; dev->chip_id = sdev->bus->chip_id;
dev->chip_rev = sdev->bus->chip_rev; dev->chip_rev = sdev->bus->chip_rev;
dev->chip_pkg = sdev->bus->chip_package; dev->chip_pkg = sdev->bus->chip_package;
......
...@@ -24,6 +24,10 @@ struct b43_bus_dev { ...@@ -24,6 +24,10 @@ struct b43_bus_dev {
struct device *dma_dev; struct device *dma_dev;
unsigned int irq; unsigned int irq;
u16 board_vendor;
u16 board_type;
u16 board_rev;
u16 chip_id; u16 chip_id;
u8 chip_rev; u8 chip_rev;
u8 chip_pkg; u8 chip_pkg;
......
...@@ -215,7 +215,6 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, ...@@ -215,7 +215,6 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
enum b43_led_behaviour *behaviour, enum b43_led_behaviour *behaviour,
bool *activelow) bool *activelow)
{ {
struct ssb_bus *bus = dev->sdev->bus;
u8 sprom[4]; u8 sprom[4];
sprom[0] = dev->dev->bus_sprom->gpio0; sprom[0] = dev->dev->bus_sprom->gpio0;
...@@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, ...@@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
case 0: case 0:
*behaviour = B43_LED_ACTIVITY; *behaviour = B43_LED_ACTIVITY;
*activelow = 1; *activelow = 1;
if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ)
*behaviour = B43_LED_RADIO_ALL; *behaviour = B43_LED_RADIO_ALL;
break; break;
case 1: case 1:
*behaviour = B43_LED_RADIO_B; *behaviour = B43_LED_RADIO_B;
if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK)
*behaviour = B43_LED_ASSOC; *behaviour = B43_LED_ASSOC;
break; break;
case 2: case 2:
......
...@@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) ...@@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev)
void b43_phy_inita(struct b43_wldev *dev) void b43_phy_inita(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
/* This lowlevel A-PHY init is also called from G-PHY init. /* This lowlevel A-PHY init is also called from G-PHY init.
...@@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev) ...@@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev)
b43_radio_init2060(dev); b43_radio_init2060(dev);
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
((bus->boardinfo.type == SSB_BOARD_BU4306) || ((dev->dev->board_type == SSB_BOARD_BU4306) ||
(bus->boardinfo.type == SSB_BOARD_BU4309))) { (dev->dev->board_type == SSB_BOARD_BU4309))) {
; //TODO: A PHY LO ; //TODO: A PHY LO
} }
......
...@@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) ...@@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
/* The next check will be needed in two seconds, or later. */ /* The next check will be needed in two seconds, or later. */
phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
(dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) (dev->dev->board_type == SSB_BOARD_BU4306))
return; /* No software txpower adjustment needed */ return; /* No software txpower adjustment needed */
result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
......
...@@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) ...@@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
static void b43_phy_initb5(struct b43_wldev *dev) static void b43_phy_initb5(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g; struct b43_phy_g *gphy = phy->g;
u16 offset, value; u16 offset, value;
...@@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev) ...@@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev)
if (phy->analog == 1) { if (phy->analog == 1) {
b43_radio_set(dev, 0x007A, 0x0050); b43_radio_set(dev, 0x007A, 0x0050);
} }
if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) && if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) &&
(bus->boardinfo.type != SSB_BOARD_BU4306)) { (dev->dev->board_type != SSB_BOARD_BU4306)) {
value = 0x2120; value = 0x2120;
for (offset = 0x00A8; offset < 0x00C7; offset++) { for (offset = 0x00A8; offset < 0x00C7; offset++) {
b43_phy_write(dev, offset, value); b43_phy_write(dev, offset, value);
...@@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) ...@@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
/* Initialize B/G PHY power control */ /* Initialize B/G PHY power control */
static void b43_phy_init_pctl(struct b43_wldev *dev) static void b43_phy_init_pctl(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g; struct b43_phy_g *gphy = phy->g;
struct b43_rfatt old_rfatt; struct b43_rfatt old_rfatt;
...@@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) ...@@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
B43_WARN_ON(phy->type != B43_PHYTYPE_G); B43_WARN_ON(phy->type != B43_PHYTYPE_G);
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
(bus->boardinfo.type == SSB_BOARD_BU4306)) (dev->dev->board_type == SSB_BOARD_BU4306))
return; return;
b43_phy_write(dev, 0x0028, 0x8018); b43_phy_write(dev, 0x0028, 0x8018);
...@@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev, ...@@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev,
static void default_radio_attenuation(struct b43_wldev *dev, static void default_radio_attenuation(struct b43_wldev *dev,
struct b43_rfatt *rf) struct b43_rfatt *rf)
{ {
struct ssb_bus *bus = dev->sdev->bus; struct b43_bus_dev *bdev = dev->dev;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
rf->with_padmix = 0; rf->with_padmix = 0;
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
bus->boardinfo.type == SSB_BOARD_BCM4309G) { dev->dev->board_type == SSB_BOARD_BCM4309G) {
if (bus->boardinfo.rev < 0x43) { if (dev->dev->board_rev < 0x43) {
rf->att = 2; rf->att = 2;
return; return;
} else if (bus->boardinfo.rev < 0x51) { } else if (dev->dev->board_rev < 0x51) {
rf->att = 3; rf->att = 3;
return; return;
} }
...@@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev, ...@@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev,
return; return;
case 1: case 1:
if (phy->type == B43_PHYTYPE_G) { if (phy->type == B43_PHYTYPE_G) {
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
&& bus->boardinfo.type == SSB_BOARD_BCM4309G && bdev->board_type == SSB_BOARD_BCM4309G
&& bus->boardinfo.rev >= 30) && bdev->board_rev >= 30)
rf->att = 3; rf->att = 3;
else if (bus->boardinfo.vendor == else if (bdev->board_vendor ==
SSB_BOARDVENDOR_BCM SSB_BOARDVENDOR_BCM
&& bus->boardinfo.type == && bdev->board_type ==
SSB_BOARD_BU4306) SSB_BOARD_BU4306)
rf->att = 3; rf->att = 3;
else else
rf->att = 1; rf->att = 1;
} else { } else {
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
&& bus->boardinfo.type == SSB_BOARD_BCM4309G && bdev->board_type == SSB_BOARD_BCM4309G
&& bus->boardinfo.rev >= 30) && bdev->board_rev >= 30)
rf->att = 7; rf->att = 7;
else else
rf->att = 6; rf->att = 6;
...@@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev, ...@@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev,
return; return;
case 2: case 2:
if (phy->type == B43_PHYTYPE_G) { if (phy->type == B43_PHYTYPE_G) {
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
&& bus->boardinfo.type == SSB_BOARD_BCM4309G && bdev->board_type == SSB_BOARD_BCM4309G
&& bus->boardinfo.rev >= 30) && bdev->board_rev >= 30)
rf->att = 3; rf->att = 3;
else if (bus->boardinfo.vendor == else if (bdev->board_vendor ==
SSB_BOARDVENDOR_BCM SSB_BOARDVENDOR_BCM
&& bus->boardinfo.type == && bdev->board_type ==
SSB_BOARD_BU4306) SSB_BOARD_BU4306)
rf->att = 5; rf->att = 5;
else if (dev->dev->chip_id == 0x4320) else if (bdev->chip_id == 0x4320)
rf->att = 4; rf->att = 4;
else else
rf->att = 3; rf->att = 3;
......
...@@ -287,7 +287,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) ...@@ -287,7 +287,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A);
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
(bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) && (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) &&
(sprom->boardflags_lo & B43_BFL_FEM))) { (sprom->boardflags_lo & B43_BFL_FEM))) {
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001);
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
...@@ -413,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) ...@@ -413,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct b43_phy_lp *lpphy = dev->phy.lp; struct b43_phy_lp *lpphy = dev->phy.lp;
b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
...@@ -433,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) ...@@ -433,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000); b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000); b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1); b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
if (bus->boardinfo.rev >= 0x18) { if (dev->dev->board_rev >= 0x18) {
b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC); b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC);
b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14); b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14);
} else { } else {
......
...@@ -424,15 +424,14 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) ...@@ -424,15 +424,14 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
{ {
struct b43_phy_n *nphy = dev->phy.n; struct b43_phy_n *nphy = dev->phy.n;
struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
int i; int i;
u16 val; u16 val;
bool workaround = false; bool workaround = false;
if (sprom->revision < 4) if (sprom->revision < 4)
workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM && workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM
binfo->type == 0x46D && && dev->dev->board_type == 0x46D
binfo->rev >= 0x41); && dev->dev->board_rev >= 0x41);
else else
workaround = workaround =
!(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
...@@ -1373,7 +1372,6 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) ...@@ -1373,7 +1372,6 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
static void b43_nphy_workarounds(struct b43_wldev *dev) static void b43_nphy_workarounds(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = phy->n; struct b43_phy_n *nphy = phy->n;
...@@ -1505,7 +1503,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) ...@@ -1505,7 +1503,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
if (sprom->boardflags2_lo & 0x100 && if (sprom->boardflags2_lo & 0x100 &&
bus->boardinfo.type == 0x8B) { dev->dev->board_type == 0x8B) {
delays1[0] = 0x1; delays1[0] = 0x1;
delays1[5] = 0x14; delays1[5] = 0x14;
} }
...@@ -3587,7 +3585,6 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) ...@@ -3587,7 +3585,6 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
*/ */
int b43_phy_initn(struct b43_wldev *dev) int b43_phy_initn(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = phy->n; struct b43_phy_n *nphy = phy->n;
...@@ -3642,8 +3639,8 @@ int b43_phy_initn(struct b43_wldev *dev) ...@@ -3642,8 +3639,8 @@ int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
if (sprom->boardflags2_lo & 0x100 || if (sprom->boardflags2_lo & 0x100 ||
(bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
bus->boardinfo.type == 0x8B)) dev->dev->board_type == 0x8B))
b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
else else
b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
......
...@@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) ...@@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev)
static void b43_wa_boards_a(struct b43_wldev *dev) static void b43_wa_boards_a(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus; if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
dev->dev->board_type == SSB_BOARD_BU4306 &&
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && dev->dev->board_rev < 0x30) {
bus->boardinfo.type == SSB_BOARD_BU4306 &&
bus->boardinfo.rev < 0x30) {
b43_phy_write(dev, 0x0010, 0xE000); b43_phy_write(dev, 0x0010, 0xE000);
b43_phy_write(dev, 0x0013, 0x0140); b43_phy_write(dev, 0x0013, 0x0140);
b43_phy_write(dev, 0x0014, 0x0280); b43_phy_write(dev, 0x0014, 0x0280);
} else { } else {
if (bus->boardinfo.type == SSB_BOARD_MP4318 && if (dev->dev->board_type == SSB_BOARD_MP4318 &&
bus->boardinfo.rev < 0x20) { dev->dev->board_rev < 0x20) {
b43_phy_write(dev, 0x0013, 0x0210); b43_phy_write(dev, 0x0013, 0x0210);
b43_phy_write(dev, 0x0014, 0x0840); b43_phy_write(dev, 0x0014, 0x0840);
} else { } else {
...@@ -486,13 +484,12 @@ static void b43_wa_boards_a(struct b43_wldev *dev) ...@@ -486,13 +484,12 @@ static void b43_wa_boards_a(struct b43_wldev *dev)
static void b43_wa_boards_g(struct b43_wldev *dev) static void b43_wa_boards_g(struct b43_wldev *dev)
{ {
struct ssb_bus *bus = dev->sdev->bus;
struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM ||
bus->boardinfo.type != SSB_BOARD_BU4306 || dev->dev->board_type != SSB_BOARD_BU4306 ||
bus->boardinfo.rev != 0x17) { dev->dev->board_rev != 0x17) {
if (phy->rev < 2) { if (phy->rev < 2) {
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
......
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