Commit c2fadcb3 authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville
Browse files

zd1211rw: support setting BSSID for AP mode

parent 5cf6cf81
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -370,16 +370,12 @@ error:
	return r;
}

/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and
 *              CR_MAC_ADDR_P2 must be overwritten
 */
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
static int zd_write_mac_addr_common(struct zd_chip *chip, const u8 *mac_addr,
				    const struct zd_ioreq32 *in_reqs,
				    const char *type)
{
	int r;
	struct zd_ioreq32 reqs[2] = {
		[0] = { .addr = CR_MAC_ADDR_P1 },
		[1] = { .addr = CR_MAC_ADDR_P2 },
	};
	struct zd_ioreq32 reqs[2] = {in_reqs[0], in_reqs[1]};

	if (mac_addr) {
		reqs[0].value = (mac_addr[3] << 24)
@@ -388,9 +384,9 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
			      |  mac_addr[0];
		reqs[1].value = (mac_addr[5] <<  8)
			      |  mac_addr[4];
		dev_dbg_f(zd_chip_dev(chip), "mac addr %pM\n", mac_addr);
		dev_dbg_f(zd_chip_dev(chip), "%s addr %pM\n", type, mac_addr);
	} else {
		dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
		dev_dbg_f(zd_chip_dev(chip), "set NULL %s\n", type);
	}

	mutex_lock(&chip->mutex);
@@ -399,6 +395,29 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
	return r;
}

/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and
 *              CR_MAC_ADDR_P2 must be overwritten
 */
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
{
	static const struct zd_ioreq32 reqs[2] = {
		[0] = { .addr = CR_MAC_ADDR_P1 },
		[1] = { .addr = CR_MAC_ADDR_P2 },
	};

	return zd_write_mac_addr_common(chip, mac_addr, reqs, "mac");
}

int zd_write_bssid(struct zd_chip *chip, const u8 *bssid)
{
	static const struct zd_ioreq32 reqs[2] = {
		[0] = { .addr = CR_BSSID_P1 },
		[1] = { .addr = CR_BSSID_P2 },
	};

	return zd_write_mac_addr_common(chip, bssid, reqs, "bssid");
}

int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
{
	int r;
+1 −0
Original line number Diff line number Diff line
@@ -881,6 +881,7 @@ static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
u8  zd_chip_get_channel(struct zd_chip *chip);
int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain);
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr);
int zd_write_bssid(struct zd_chip *chip, const u8 *bssid);
int zd_chip_switch_radio_on(struct zd_chip *chip);
int zd_chip_switch_radio_off(struct zd_chip *chip);
int zd_chip_enable_int(struct zd_chip *chip);
+24 −1
Original line number Diff line number Diff line
@@ -231,6 +231,26 @@ static int set_rx_filter(struct zd_mac *mac)
	return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
}

static int set_mac_and_bssid(struct zd_mac *mac)
{
	int r;

	if (!mac->vif)
		return -1;

	r = zd_write_mac_addr(&mac->chip, mac->vif->addr);
	if (r)
		return r;

	/* Vendor driver after setting MAC either sets BSSID for AP or
	 * filter for other modes.
	 */
	if (mac->type != NL80211_IFTYPE_AP)
		return set_rx_filter(mac);
	else
		return zd_write_bssid(&mac->chip, mac->vif->addr);
}

static int set_mc_hash(struct zd_mac *mac)
{
	struct zd_mc_hash hash;
@@ -888,7 +908,9 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
		return -EOPNOTSUPP;
	}

	return zd_write_mac_addr(&mac->chip, vif->addr);
	mac->vif = vif;

	return set_mac_and_bssid(mac);
}

static void zd_op_remove_interface(struct ieee80211_hw *hw,
@@ -896,6 +918,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
{
	struct zd_mac *mac = zd_hw_mac(hw);
	mac->type = NL80211_IFTYPE_UNSPECIFIED;
	mac->vif = NULL;
	zd_set_beacon_interval(&mac->chip, 0);
	zd_write_mac_addr(&mac->chip, NULL);
}
+1 −0
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ struct zd_mac {
	spinlock_t lock;
	spinlock_t intr_lock;
	struct ieee80211_hw *hw;
	struct ieee80211_vif *vif;
	struct housekeeping housekeeping;
	struct work_struct set_rts_cts_work;
	struct work_struct process_intr;