* [PATCHv3 4/5] mac80211: add channel switch command and beacon callbacks
From: Simon Wunderlich @ 2013-07-08 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373289250-12259-1-git-send-email-siwu@hrz.tu-chemnitz.de>
The count field in CSA must be decremented with each beacon
transmitted. This patch implements the functionality for drivers
using ieee80211_beacon_get(). Other drivers must call back manually
after reaching count == 0.
This patch also contains the handling and finish worker for the channel
switch command.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv2:
* fix documentation and style stuff
* update tracing
* change csa_active to bool
* check if csa_active when assigning beacons
* fix locking and access
* use new ieee80211_vif_change_channel to change the channel
Changes to PATCHv1:
* don't switch when CAC is active
* add hw to parameters for driver
Changes to RFCv1:
* use beacons as supplied from nl80211 without generating/parsing them
* update beacons using offsets
* report back by calling the channel switch event in cfg80211
---
include/net/mac80211.h | 34 +++++++++++++
net/mac80211/cfg.c | 116 +++++++++++++++++++++++++++++++++++++++++++-
net/mac80211/driver-ops.h | 13 +++++
net/mac80211/ieee80211_i.h | 13 +++++
net/mac80211/iface.c | 2 +
net/mac80211/trace.h | 26 ++++++++++
net/mac80211/tx.c | 80 ++++++++++++++++++++++++++++++
7 files changed, 282 insertions(+), 2 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index aadf4eb..0eb636b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1084,6 +1084,7 @@ enum ieee80211_vif_flags {
* @addr: address of this interface
* @p2p: indicates whether this AP or STA interface is a p2p
* interface, i.e. a GO or p2p-sta respectively
+ * @csa_active: marks whether a channel switch is going on
* @driver_flags: flags/capabilities the driver has for this interface,
* these need to be set (or cleared) when the interface is added
* or, if supported by the driver, the interface type is changed
@@ -1106,6 +1107,7 @@ struct ieee80211_vif {
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
bool p2p;
+ bool csa_active;
u8 cab_queue;
u8 hw_queue[IEEE80211_NUM_ACS];
@@ -2637,6 +2639,16 @@ enum ieee80211_roc_type {
* @ipv6_addr_change: IPv6 address assignment on the given interface changed.
* Currently, this is only called for managed or P2P client interfaces.
* This callback is optional; it must not sleep.
+ *
+ * @channel_switch_beacon: Starts a channel switch to a new channel.
+ * Beacons are modified to include CSA or ECSA IEs before calling this
+ * function. The corresponding count fields in these IEs must be
+ * decremented, and when they reach zero the driver must call
+ * ieee80211_csa_finish(). Drivers which use ieee80211_beacon_get()
+ * get the csa counter decremented by mac80211, but must check if it is
+ * zero using ieee80211_csa_is_complete() after the beacon has been
+ * transmitted and then call ieee80211_csa_finish().
+ *
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -2824,6 +2836,9 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct inet6_dev *idev);
#endif
+ void (*channel_switch_beacon)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_chan_def *chandef);
};
/**
@@ -3319,6 +3334,25 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
}
/**
+ * ieee80211_csa_finish - notify mac80211 about channel switch
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ *
+ * After a channel switch announcement was scheduled and the counter in this
+ * announcement hit zero, this function must be called by the driver to
+ * notify mac80211 that the channel can be changed.
+ */
+void ieee80211_csa_finish(struct ieee80211_vif *vif);
+
+/**
+ * ieee80211_csa_is_complete - find out if counters reached zero
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ *
+ * This function returns whether the channel switch counters reached zero.
+ */
+bool ieee80211_csa_is_complete(struct ieee80211_vif *vif);
+
+
+/**
* ieee80211_proberesp_get - retrieve a Probe Response template
* @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a99c9a8..b32e4db 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -854,8 +854,8 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
return 0;
}
-static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_beacon_data *params)
+int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_beacon_data *params)
{
struct beacon_data *new, *old;
int new_head_len, new_tail_len;
@@ -1018,6 +1018,12 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ /* don't allow changing the beacon while CSA is in place - offset
+ * of channel switch counter may change
+ */
+ if (sdata->vif.csa_active)
+ return -EBUSY;
+
old = rtnl_dereference(sdata->u.ap.beacon);
if (!old)
return -ENOENT;
@@ -2840,6 +2846,111 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
return new_beacon;
}
+void ieee80211_csa_finalize_work(struct work_struct *work)
+{
+ struct ieee80211_sub_if_data *sdata =
+ container_of(work, struct ieee80211_sub_if_data,
+ csa_finalize_work);
+ struct ieee80211_local *local = sdata->local;
+ int err, changed;
+
+ if (!ieee80211_sdata_running(sdata))
+ return;
+
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
+ return;
+
+ sdata->radar_required = sdata->csa_radar_required;
+ err = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
+ &changed);
+ if (WARN_ON(err < 0))
+ return;
+
+ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
+ if (err < 0)
+ return;
+
+ changed |= err;
+ kfree(sdata->u.ap.next_beacon);
+ sdata->u.ap.next_beacon = NULL;
+
+ ieee80211_wake_queues_by_reason(&sdata->local->hw,
+ IEEE80211_MAX_QUEUE_MAP,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+
+ ieee80211_bss_info_change_notify(sdata, changed);
+
+ cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef);
+}
+
+static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_csa_settings *params)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_chanctx *chanctx;
+ int err;
+
+ if (!list_empty(&local->roc_list) || local->scanning)
+ return -EBUSY;
+
+ if (sdata->wdev.cac_started)
+ return -EBUSY;
+
+ /* don't handle if chanctx is used */
+ if (local->use_chanctx)
+ return -EBUSY;
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (!chanctx_conf) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+
+ /* don't handle for multi-VIF cases */
+ chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
+ if (chanctx->refcount > 1) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+ rcu_read_unlock();
+
+ /* only handle AP for now. */
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ sdata->u.ap.next_beacon = cfg80211_beacon_dup(¶ms->beacon_after);
+ if (!sdata->u.ap.next_beacon)
+ return -ENOMEM;
+
+ sdata->csa_counter_offset_beacon = params->counter_offset_beacon;
+ sdata->csa_counter_offset_presp = params->counter_offset_presp;
+ sdata->csa_radar_required = params->radar_required;
+
+ if (params->block_tx)
+ ieee80211_stop_queues_by_reason(&local->hw,
+ IEEE80211_MAX_QUEUE_MAP,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa);
+ if (err < 0)
+ return err;
+
+ local->csa_chandef = params->chandef;
+ sdata->vif.csa_active = true;
+
+ ieee80211_bss_info_change_notify(sdata, err);
+ drv_channel_switch_beacon(sdata, ¶ms->chandef);
+
+ return 0;
+}
+
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan,
unsigned int wait, const u8 *buf, size_t len,
@@ -3557,4 +3668,5 @@ struct cfg80211_ops mac80211_config_ops = {
.get_et_strings = ieee80211_get_et_strings,
.get_channel = ieee80211_cfg_get_channel,
.start_radar_detection = ieee80211_start_radar_detection,
+ .channel_switch = ieee80211_channel_switch,
};
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index b931c96..b3ea11f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1072,4 +1072,17 @@ static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
}
#endif
+static inline void
+drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_chan_def *chandef)
+{
+ struct ieee80211_local *local = sdata->local;
+
+ if (local->ops->channel_switch_beacon) {
+ trace_drv_channel_switch_beacon(local, sdata, chandef);
+ local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
+ chandef);
+ }
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e34eb5f..2a22379 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -259,6 +259,8 @@ struct ieee80211_if_ap {
struct beacon_data __rcu *beacon;
struct probe_resp __rcu *probe_resp;
+ /* to be used after channel switch. */
+ struct cfg80211_beacon_data *next_beacon;
struct list_head vlans;
struct ps_data ps;
@@ -716,6 +718,11 @@ struct ieee80211_sub_if_data {
struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
+ struct work_struct csa_finalize_work;
+ int csa_counter_offset_beacon;
+ int csa_counter_offset_presp;
+ bool csa_radar_required;
+
/* used to reconfigure hardware SM PS */
struct work_struct recalc_smps;
@@ -1344,6 +1351,9 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free);
void ieee80211_sw_roc_work(struct work_struct *work);
void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
+/* channel switch handling */
+void ieee80211_csa_finalize_work(struct work_struct *work);
+
/* interface handling */
int ieee80211_iface_init(void);
void ieee80211_iface_exit(void);
@@ -1365,6 +1375,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
+int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_beacon_data *params);
+
static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
{
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index a2a8250..671fe7c 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -804,6 +804,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
cancel_work_sync(&local->dynamic_ps_enable_work);
cancel_work_sync(&sdata->recalc_smps);
+ cancel_work_sync(&sdata->csa_finalize_work);
cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
@@ -1267,6 +1268,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
skb_queue_head_init(&sdata->skb_queue);
INIT_WORK(&sdata->work, ieee80211_iface_work);
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
+ INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
switch (type) {
case NL80211_IFTYPE_P2P_GO:
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index c215fafd7..1aba645 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1906,6 +1906,32 @@ TRACE_EVENT(api_radar_detected,
)
);
+TRACE_EVENT(drv_channel_switch_beacon,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_chan_def *chandef),
+
+ TP_ARGS(local, sdata, chandef),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ CHANDEF_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ CHANDEF_ASSIGN(chandef);
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT " channel switch to " CHANDEF_PR_FMT,
+ LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG
+ )
+);
+
+
#ifdef CONFIG_MAC80211_MESSAGE_TRACING
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4105d0c..76b2538 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2320,6 +2320,83 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
return 0;
}
+void ieee80211_csa_finish(struct ieee80211_vif *vif)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+ vif->csa_active = false;
+ ieee80211_queue_work(&sdata->local->hw,
+ &sdata->csa_finalize_work);
+}
+EXPORT_SYMBOL(ieee80211_csa_finish);
+
+static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata,
+ struct beacon_data *beacon)
+{
+ struct probe_resp *resp;
+ int counter_offset_beacon = sdata->csa_counter_offset_beacon;
+ int counter_offset_presp = sdata->csa_counter_offset_presp;
+
+ /* warn if the driver did not check for/react to csa completeness */
+ if (WARN_ON(((u8 *)beacon->tail)[counter_offset_beacon] == 0))
+ return;
+
+ ((u8 *)beacon->tail)[counter_offset_beacon]--;
+
+ if (!counter_offset_presp)
+ return;
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP) {
+ rcu_read_lock();
+ resp = rcu_dereference(sdata->u.ap.probe_resp);
+
+ /* if nl80211 accepted the offset, this should not happen. */
+ if (WARN_ON(!resp)) {
+ rcu_read_unlock();
+ return;
+ }
+ resp->data[counter_offset_presp]--;
+ }
+}
+
+bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct beacon_data *beacon = NULL;
+ u8 *beacon_data;
+ size_t beacon_data_len;
+ int counter_beacon = sdata->csa_counter_offset_beacon;
+ int ret = false;
+
+ if (!ieee80211_sdata_running(sdata))
+ return false;
+
+ rcu_read_lock();
+ if (vif->type == NL80211_IFTYPE_AP) {
+ struct ieee80211_if_ap *ap = &sdata->u.ap;
+
+ beacon = rcu_dereference(ap->beacon);
+ if (WARN_ON(!beacon || !beacon->tail))
+ goto out;
+ beacon_data = beacon->tail;
+ beacon_data_len = beacon->tail_len;
+ } else {
+ WARN_ON(1);
+ goto out;
+ }
+
+ if (WARN_ON(counter_beacon > beacon_data_len))
+ goto out;
+
+ if (beacon_data[counter_beacon] == 0)
+ ret = true;
+ out:
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(ieee80211_csa_is_complete);
+
struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length)
@@ -2350,6 +2427,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct beacon_data *beacon = rcu_dereference(ap->beacon);
if (beacon) {
+ if (sdata->vif.csa_active)
+ ieee80211_update_csa(sdata, beacon);
+
/*
* headroom, head length,
* tail length and maximum TIM length
--
1.7.10.4
^ permalink raw reply related
* [PATCHv3 1/5] nl80211/cfg80211: add channel switch command
From: Simon Wunderlich @ 2013-07-08 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373289250-12259-1-git-send-email-siwu@hrz.tu-chemnitz.de>
To allow channel switch announcements within beacons, add
the channel switch command to nl80211/cfg80211. This is
implementation is intended for AP and (later) IBSS mode.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv2:
* define csa_ies as static to save stack size
* add wiphy flag and cmd for channel_switch
* move NL80211_ATTR_CSA_C_OFF_BEACON into csa_ies
Changes to RFCv1:
* accept and pass CSA IEs and after-change IEs
* use parameter structure instead of individual parameters
---
include/net/cfg80211.h | 30 ++++++++++
include/uapi/linux/nl80211.h | 29 ++++++++++
net/wireless/nl80211.c | 126 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 184 insertions(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4940960..249ac42 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -639,6 +639,30 @@ struct cfg80211_ap_settings {
};
/**
+ * struct cfg80211_csa_settings - channel switch settings
+ *
+ * Used for channel switch
+ *
+ * @chandef: defines the channel to use after the switch
+ * @beacon_csa: beacon data while performing the switch
+ * @counter_offset_beacon: offset for the counter within the beacon (tail)
+ * @counter_offset_presp: offset for the counter within the probe response
+ * @beacon_after: beacon data to be used on the new channel
+ * @radar_required: whether radar detection is required on the new channel
+ * @block_tx: whether transmissions should be blocked while changing
+ * @count: number of beacons until switch
+ */
+struct cfg80211_csa_settings {
+ struct cfg80211_chan_def chandef;
+ struct cfg80211_beacon_data beacon_csa;
+ u16 counter_offset_beacon, counter_offset_presp;
+ struct cfg80211_beacon_data beacon_after;
+ bool radar_required;
+ bool block_tx;
+ u8 count;
+};
+
+/**
* enum station_parameters_apply_mask - station parameter values to apply
* @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
* @STATION_PARAM_APPLY_CAPABILITY: apply new capability
@@ -2311,6 +2335,9 @@ struct cfg80211_ops {
u16 duration);
void (*crit_proto_stop)(struct wiphy *wiphy,
struct wireless_dev *wdev);
+ int (*channel_switch)(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_csa_settings *params);
};
/*
@@ -2376,6 +2403,8 @@ struct cfg80211_ops {
* @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
* @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
* @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
+ * @WIPHY_FLAG_HAS_CHANNEL_SWITCH_BEACON: Device supports channel switch in
+ * beaconing mode (AP, IBSS, Mesh, ...).
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -2400,6 +2429,7 @@ enum wiphy_flags {
WIPHY_FLAG_OFFCHAN_TX = BIT(20),
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
+ WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23),
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index de0ce80..4049cb8 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -648,6 +648,16 @@
* @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
* return back to normal.
*
+ * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the
+ * the new channel information (Channel Switch Announcement - CSA)
+ * in the beacon for some time (as defined in the
+ * %NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the
+ * new channel. Userspace provides the new channel information (using
+ * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel
+ * width). %NL80211_ATTR_CH_SWITCH_BLOCK_TX may be supplied to inform
+ * other station that transmission must be blocked until the channel
+ * switch is complete.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -810,6 +820,7 @@ enum nl80211_commands {
NL80211_CMD_CRIT_PROTOCOL_START,
NL80211_CMD_CRIT_PROTOCOL_STOP,
+ NL80211_CMD_CHANNEL_SWITCH,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1436,6 +1447,18 @@ enum nl80211_commands {
* allowed to be used with the first @NL80211_CMD_SET_STATION command to
* update a TDLS peer STA entry.
*
+ * @NL80211_ATTR_CH_SWITCH_COUNT: u32 attribute specifying the number of TBTT's
+ * until the channel switch event.
+ * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
+ * must be blocked on the current channel (before the channel switch
+ * operation).
+ * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
+ * for the time while performing a channel switch.
+ * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
+ * field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+ * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
+ * field in the probe response (%NL80211_ATTR_PROBE_RESP).
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1736,6 +1759,12 @@ enum nl80211_attrs {
NL80211_ATTR_PEER_AID,
+ NL80211_ATTR_CH_SWITCH_COUNT,
+ NL80211_ATTR_CH_SWITCH_BLOCK_TX,
+ NL80211_ATTR_CSA_IES,
+ NL80211_ATTR_CSA_C_OFF_BEACON,
+ NL80211_ATTR_CSA_C_OFF_PRESP,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index be64cd4..4e86a56 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -349,6 +349,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
+ [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
+ [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
+ [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
+ [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
+ [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
};
/* policy for the key attributes */
@@ -1393,6 +1398,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
if (state->split) {
CMD(crit_proto_start, CRIT_PROTOCOL_START);
CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
+ if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
+ CMD(channel_switch, CHANNEL_SWITCH);
}
#ifdef CONFIG_NL80211_TESTMODE
@@ -5576,6 +5583,115 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
return err;
}
+static int nl80211_channel_switch(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_csa_settings params;
+ /* csa_ies is defined static to avoid waste of stack size - this
+ * function is called under RTNL lock, so this should not be a problem.
+ */
+ static struct nlattr *csa_ies[NL80211_ATTR_MAX+1];
+ u8 radar_detect_width = 0;
+ int err;
+
+ if (!rdev->ops->channel_switch ||
+ !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
+ return -EOPNOTSUPP;
+
+ /* may add IBSS support later */
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
+
+ memset(¶ms, 0, sizeof(params));
+
+ if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
+ !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
+ return -EINVAL;
+
+ /* only important for AP, IBSS and mesh create IEs internally */
+ if (!info->attrs[NL80211_ATTR_CSA_IES])
+ return -EINVAL;
+
+ /* useless if AP is not running */
+ if (!wdev->beacon_interval)
+ return -EINVAL;
+
+ params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
+
+ err = nl80211_parse_beacon(info->attrs, ¶ms.beacon_after);
+ if (err)
+ return err;
+
+ err = nla_parse_nested(csa_ies, NL80211_ATTR_MAX,
+ info->attrs[NL80211_ATTR_CSA_IES],
+ nl80211_policy);
+ if (err)
+ return err;
+
+ err = nl80211_parse_beacon(csa_ies, ¶ms.beacon_csa);
+ if (err)
+ return err;
+
+ if (!csa_ies[NL80211_ATTR_CSA_C_OFF_BEACON])
+ return -EINVAL;
+
+ params.counter_offset_beacon =
+ nla_get_u16(csa_ies[NL80211_ATTR_CSA_C_OFF_BEACON]);
+ if (params.counter_offset_beacon > params.beacon_csa.tail_len)
+ return -EINVAL;
+
+ /* sanity check - counter should be the same this should be the same */
+ if (params.beacon_csa.tail[params.counter_offset_beacon] !=
+ params.count)
+ return -EINVAL;
+
+ if (csa_ies[NL80211_ATTR_CSA_C_OFF_PRESP]) {
+ params.counter_offset_presp =
+ nla_get_u16(csa_ies[NL80211_ATTR_CSA_C_OFF_PRESP]);
+ if (params.counter_offset_presp >
+ params.beacon_csa.probe_resp_len)
+ return -EINVAL;
+
+ if (params.beacon_csa.probe_resp[params.counter_offset_presp] !=
+ params.count)
+ return -EINVAL;
+ }
+
+ err = nl80211_parse_chandef(rdev, info, ¶ms.chandef);
+ if (err)
+ return err;
+
+ if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef))
+ return -EINVAL;
+
+ err = cfg80211_chandef_dfs_required(wdev->wiphy, ¶ms.chandef);
+ if (err < 0)
+ return err;
+
+ if (err)
+ radar_detect_width = BIT(params.chandef.width);
+ else
+ radar_detect_width = 0;
+
+ err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
+ params.chandef.chan,
+ CHAN_MODE_SHARED,
+ radar_detect_width);
+ if (err)
+ return err;
+
+ if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
+ params.block_tx = true;
+
+ err = rdev->ops->channel_switch(&rdev->wiphy, dev, ¶ms);
+
+ return err;
+}
+
static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
u32 seq, int flags,
struct cfg80211_registered_device *rdev,
@@ -9048,7 +9164,15 @@ static struct genl_ops nl80211_ops[] = {
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
- }
+ },
+ {
+ .cmd = NL80211_CMD_CHANNEL_SWITCH,
+ .doit = nl80211_channel_switch,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
--
1.7.10.4
^ permalink raw reply related
* [PATCHv3 3/5] mac80211: allow chanctx to change channels
From: Simon Wunderlich @ 2013-07-08 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373289250-12259-1-git-send-email-siwu@hrz.tu-chemnitz.de>
This adds mac80211/chanctx code to allow to change a channel definition
of an active channel context. This will be used for the channel switch
command added later.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
include/net/mac80211.h | 4 ++++
net/mac80211/chan.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 4 ++++
3 files changed, 63 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7c5dc78..aadf4eb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -152,11 +152,13 @@ struct ieee80211_low_level_stats {
* @IEEE80211_CHANCTX_CHANGE_WIDTH: The channel width changed
* @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed
* @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed
+ * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel
*/
enum ieee80211_chanctx_change {
IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2),
+ IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3)
};
/**
@@ -222,6 +224,7 @@ struct ieee80211_chanctx_conf {
* @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed,
* note that this is only called when it changes after the channel
* context had been assigned.
+ * @BSS_CHANGED_CHANNEL: The operating channel of this interface changed.
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -246,6 +249,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_P2P_PS = 1<<19,
BSS_CHANGED_BEACON_INFO = 1<<20,
BSS_CHANGED_BANDWIDTH = 1<<21,
+ BSS_CHANGED_CHANNEL = 1<<22,
/* when adding here, make sure to change ieee80211_reconfig */
};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 03e8d2e..7816703 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -410,6 +410,61 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
return ret;
}
+int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
+ const struct cfg80211_chan_def *chandef,
+ u32 *changed)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_chanctx_conf *conf;
+ struct ieee80211_chanctx *ctx;
+ int ret;
+ u32 chanctx_changed = 0;
+
+ if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
+ IEEE80211_CHAN_DISABLED))
+ return -EINVAL;
+
+ mutex_lock(&local->chanctx_mtx);
+ conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
+ lockdep_is_held(&local->chanctx_mtx));
+ if (!conf) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ctx = container_of(conf, struct ieee80211_chanctx, conf);
+ if (ctx->refcount != 1) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (sdata->vif.bss_conf.chandef.width != chandef->width) {
+ chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH;
+ *changed |= BSS_CHANGED_BANDWIDTH;
+ }
+
+ sdata->vif.bss_conf.chandef = *chandef;
+ ctx->conf.def = *chandef;
+
+ chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
+ *changed |= BSS_CHANGED_CHANNEL;
+ drv_change_chanctx(local, ctx, chanctx_changed);
+
+ if (!local->use_chanctx) {
+ local->_oper_chandef = *chandef;
+ ieee80211_hw_config(local, 0);
+ }
+
+ ieee80211_recalc_chanctx_chantype(local, ctx);
+ ieee80211_recalc_smps_chanctx(local, ctx);
+ ieee80211_recalc_radar_chanctx(local, ctx);
+
+ ret = 0;
+ out:
+ mutex_unlock(&local->chanctx_mtx);
+ return ret;
+}
+
int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
const struct cfg80211_chan_def *chandef,
u32 *changed)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 683751a..e34eb5f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1625,6 +1625,10 @@ int __must_check
ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
const struct cfg80211_chan_def *chandef,
u32 *changed);
+int __must_check
+ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
+ const struct cfg80211_chan_def *chandef,
+ u32 *changed);
void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
--
1.7.10.4
^ permalink raw reply related
* [PATCHv3 2/5] mac80211: add functions to duplicate a cfg80211_beacon
From: Simon Wunderlich @ 2013-07-08 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1373289250-12259-1-git-send-email-siwu@hrz.tu-chemnitz.de>
For the channel switch announcement, it is required to set a new beacon
after the driver arrived on the new channel. The new beacon will be set
by nl80211, but is required to duplicate the beacon as the original
memory within the netlink message will be gone.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv2:
* allocate only one memory chunk
---
net/mac80211/cfg.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 8184d12..a99c9a8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2784,6 +2784,62 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
return 0;
}
+static struct cfg80211_beacon_data *
+cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
+{
+ struct cfg80211_beacon_data *new_beacon;
+ u8 *pos;
+ int len;
+
+ len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
+ beacon->proberesp_ies_len + beacon->assocresp_ies_len +
+ beacon->probe_resp_len;
+
+ new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
+ if (!new_beacon)
+ return NULL;
+
+ pos = (u8 *)(new_beacon + 1);
+ if (beacon->head_len) {
+ new_beacon->head_len = beacon->head_len;
+ new_beacon->head = pos;
+ memcpy(pos, beacon->head, beacon->head_len);
+ pos += beacon->head_len;
+ }
+ if (beacon->tail_len) {
+ new_beacon->tail_len = beacon->tail_len;
+ new_beacon->tail = pos;
+ memcpy(pos, beacon->tail, beacon->tail_len);
+ pos += beacon->tail_len;
+ }
+ if (beacon->beacon_ies_len) {
+ new_beacon->beacon_ies_len = beacon->beacon_ies_len;
+ new_beacon->beacon_ies = pos;
+ memcpy(pos, beacon->beacon_ies, beacon->beacon_ies_len);
+ pos += beacon->beacon_ies_len;
+ }
+ if (beacon->proberesp_ies_len) {
+ new_beacon->proberesp_ies_len = beacon->proberesp_ies_len;
+ new_beacon->proberesp_ies = pos;
+ memcpy(pos, beacon->proberesp_ies, beacon->proberesp_ies_len);
+ pos += beacon->proberesp_ies_len;
+ }
+ if (beacon->assocresp_ies_len) {
+ new_beacon->assocresp_ies_len = beacon->assocresp_ies_len;
+ new_beacon->assocresp_ies = pos;
+ memcpy(pos, beacon->assocresp_ies, beacon->assocresp_ies_len);
+ pos += beacon->assocresp_ies_len;
+ }
+ if (beacon->probe_resp_len) {
+ new_beacon->probe_resp_len = beacon->probe_resp_len;
+ beacon->probe_resp = pos;
+ memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
+ pos += beacon->probe_resp_len;
+ }
+
+ return new_beacon;
+}
+
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan,
unsigned int wait, const u8 *buf, size_t len,
--
1.7.10.4
^ permalink raw reply related
* [PATCHv3 0/5] add master channel switch announcement support
From: Simon Wunderlich @ 2013-07-08 13:14 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
This is the 3rd edition of the CSA support patch series. This patchset adds
generic channel switch support for AP. This is required for DFS operation
(e.g. Wi-Fi Alliance requires this for 802.11h certification). This will also
be required for IBSS-DFS later.
Changes from PATCHv2:
* change_channel function for channel context
* announce csa support via wiphy flag/cmd
* put offset into nested csa information for nl80211 command
* various locking, style, documentation and some more minor issues
* rebased on latest mac80211-next master
The rough design is:
* userspace asks kernel to switch a channel using the new NL80211_CMD_CHANNEL_SWITCH
command. It supplies IE information for the time while staying on the old channel and
announcing the switch, and IE information for after the switch to the new channel.
* IE information contains the beacon and optionally probe responses, which should
include (E)CSA IEs for the CSA case. Furthermore an offset is provided (for beacon
and probe response) to point to the counter field within the channel switch IEs.
* The driver gets the new beacons passed and must set them, and decrement the
counter field. When it reaches 0, the channel is changed and userspace notified.
As always, any comments are appreciated.
Cheers,
Simon
Simon Wunderlich (5):
nl80211/cfg80211: add channel switch command
mac80211: add functions to duplicate a cfg80211_beacon
mac80211: allow chanctx to change channels
mac80211: add channel switch command and beacon callbacks
ath9k: enable CSA functionality in ath9k
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +
drivers/net/wireless/ath/ath9k/beacon.c | 21 ++++
drivers/net/wireless/ath/ath9k/init.c | 1 +
drivers/net/wireless/ath/ath9k/main.c | 17 +++
drivers/net/wireless/ath/ath9k/xmit.c | 2 +
include/net/cfg80211.h | 30 ++++++
include/net/mac80211.h | 38 +++++++
include/uapi/linux/nl80211.h | 29 ++++++
net/mac80211/cfg.c | 172 ++++++++++++++++++++++++++++++-
net/mac80211/chan.c | 55 ++++++++++
net/mac80211/driver-ops.h | 13 +++
net/mac80211/ieee80211_i.h | 17 +++
net/mac80211/iface.c | 2 +
net/mac80211/trace.h | 26 +++++
net/mac80211/tx.c | 80 ++++++++++++++
net/wireless/nl80211.c | 126 +++++++++++++++++++++-
16 files changed, 628 insertions(+), 3 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Re: [PATCH V2] vlan priority handling in WMM
From: Johannes Berg @ 2013-07-08 12:15 UTC (permalink / raw)
To: voncken; +Cc: linux-wireless
In-Reply-To: <006c01ce7bc7$608c2a30$21a47e90$@acksys.fr>
On Mon, 2013-07-08 at 12:39 +0200, voncken wrote:
> > > The vlan Tag contain three bit for priority. The value 0 indicate
> no
> > > priority (on this case the VLAN tag contain only VID). The
> vlan_tci
> > > field is set to zero if the frame do not contain the vlan tag. So
> if
> > > we have not a vlan tag or no priority in VLAN tag the priority
> value
> > > is always 0.
>
> > Yes but don't we know that the vlan_tci field is valid?
>
> > I don't think you're correct in that 0 means "no priority present",
> it actually means "best effort" as far as I can tell. Ignoring the
> VLAN tag when the field is 0 would mean we could use a higher priority
> from the contents of the frame, which would not be desired?
>
> I can add a test with the macro vlan_tx_tag_present() to verify if the
> vlan_tci field is valid.
> I test the value 0 to skip the VLAN priority and use the dscp priority
> in this case. The priority 0 in VLAN tag is often use to turn off the
> QOS, because not bit is allowed for it.
What do you mean by "is often used"? I don't see how that would be the
case? Are you saying routers commonly ignore the VLAN priority value if
it's 0? That would seem odd?
> For me is it correct. Nevertheless, if you prefer, I can test only the
> vlan_tci validity and in this case always use the VLAN priority.
I don't know! Since you don't seem to really know either, we should ask
somebody who knows, I think. Maybe you should Cc netdev with this
question on the patch or so?
> Sorry I made a mistake 0xE000 >>13 = 0x0007 and not 0x0003, and 7 is
> a 3 bits value.
Ah yes, I made the same mistake, sorry.
johannes
^ permalink raw reply
* Re: [PATCH v5 1/2] iw: use updated structures and enums for packet pattern
From: Johannes Berg @ 2013-07-08 11:19 UTC (permalink / raw)
To: Bing Zhao; +Cc: linux-wireless, Amitkumar Karwar
In-Reply-To: <1372449225-10652-1-git-send-email-bzhao@marvell.com>
On Fri, 2013-06-28 at 12:53 -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <akarwar@marvell.com>
>
> They are renamed in new nl80211.h so that they can be used for
> new feature. This patch uses those updated structures and enums
> to make the code look nicer.
Both applied, thanks.
johannes
^ permalink raw reply
* Re: [PATCH v5] cfg80211/nl80211: Add packet coalesce support
From: Johannes Berg @ 2013-07-08 11:15 UTC (permalink / raw)
To: Bing Zhao; +Cc: linux-wireless, Amitkumar Karwar
In-Reply-To: <1372445486-10466-1-git-send-email-bzhao@marvell.com>
On Fri, 2013-06-28 at 11:51 -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <akarwar@marvell.com>
>
> In most cases, host that receives IPv4 and IPv6 multicast/broadcast
> packets does not do anything with these packets. Therefore the
> reception of these unwanted packets causes unnecessary processing
> and power consumption.
>
> Packet coalesce feature helps to reduce number of received
> interrupts to host by buffering these packets in firmware/hardware
> for some predefined time. Received interrupt will be generated when
> one of the following events occur.
> a) Expiration of hardware timer whose expiration time is set to
> maximum coalescing delay of matching coalesce rule.
> b) Coalescing buffer in hardware reaches it's limit.
> c) Packet doesn't match any of the configured coalesce rules.
>
> This patch adds set/get configuration support for packet coalesce.
> User needs to configure following parameters for creating a coalesce
> rule.
> a) Maximum coalescing delay
> b) List of packet patterns which needs to be matched
> c) Condition for coalescence. pattern 'match' or 'no match'
> Multiple such rules can be created.
>
> This feature needs to be advertised during driver initialization.
> Drivers are supposed to do required firmware/hardware settings based
> on user configuration.
Applied.
johannes
^ permalink raw reply
* Re: [PATCHv5 00/18] Add support for 5 and 10 MHz channels
From: Johannes Berg @ 2013-07-08 11:03 UTC (permalink / raw)
To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1372352340-20663-1-git-send-email-siwu@hrz.tu-chemnitz.de>
On Thu, 2013-06-27 at 18:58 +0200, Simon Wunderlich wrote:
> As always, any comments are appreciated!
Compilation is broken in the middle of this series so I'm dropping this.
joahnnes
^ permalink raw reply
* RE: [PATCH V2] vlan priority handling in WMM
From: voncken @ 2013-07-08 10:39 UTC (permalink / raw)
To: 'Johannes Berg'; +Cc: linux-wireless
In-Reply-To: <1373273460.8312.3.camel@jlt4.sipsolutions.net>
> > The vlan Tag contain three bit for priority. The value 0 indicate no
> > priority (on this case the VLAN tag contain only VID). The vlan_tci
> > field is set to zero if the frame do not contain the vlan tag. So if
> > we have not a vlan tag or no priority in VLAN tag the priority value
> > is always 0.
> Yes but don't we know that the vlan_tci field is valid?
> I don't think you're correct in that 0 means "no priority present", it actually means "best effort" as far as I can tell. Ignoring the VLAN tag when the field is 0 would mean we could use a higher priority from the contents of the frame, which would not be desired?
I can add a test with the macro vlan_tx_tag_present() to verify if the vlan_tci field is valid.
I test the value 0 to skip the VLAN priority and use the dscp priority in this case. The priority 0 in VLAN tag is often use to turn off the QOS, because not bit is allowed for it.
For me is it correct. Nevertheless, if you prefer, I can test only the vlan_tci validity and in this case always use the VLAN priority.
> > Sorry but I don't understand. The vlan_tci field it is a __u16 value
> > (defined in include/linux/skbuff.h), the VLAN_PRIO_MASK is set to
> > 0xE000 and VLAN_PRIO_SHIFT is set to 13 (defined in
> > include/linux/if_vlan.h), the vlan_priority is an unsigned char. For
> > me the vlan_priority contain a 3-bit value (0xE000 >>13 = 0x0003), why
> > 2 ?
> Umm? No? Think again about what hweight(0x0003) is.
Sorry I made a mistake 0xE000 >>13 = 0x0007 and not 0x0003, and 7 is a 3 bits value.
Cedric
^ permalink raw reply
* Re: [PATCH v2 5/5] rt2x00: rt2800lib: add EEPROM map for the RT3593 chipset
From: Gertjan van Wingerde @ 2013-07-08 10:06 UTC (permalink / raw)
To: Gabor Juhos
Cc: John Linville, linux-wireless@vger.kernel.org, rt2x00 Users List
In-Reply-To: <1373275556-6482-6-git-send-email-juhosg@openwrt.org>
On Mon, Jul 8, 2013 at 11:25 AM, Gabor Juhos <juhosg@openwrt.org> wrote:
> Three-chain devices are using a different
> EEPROM layout than the rest of the chipsets.
> Add a new map which describes the new layout
> and use that for the RT3593 chipset.
>
> The index values has been computed from the
> EEPROM_EXT_* defines, which can be found in
> the 'include/chip/rt3593.h' file in the
> Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
> driver.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
> Changes since v1: ---
> ---
> drivers/net/wireless/rt2x00/rt2800.h | 6 ++++
> drivers/net/wireless/rt2x00/rt2800lib.c | 48 ++++++++++++++++++++++++++++++-
> 2 files changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
> index bc5c695..9216834 100644
> --- a/drivers/net/wireless/rt2x00/rt2800.h
> +++ b/drivers/net/wireless/rt2x00/rt2800.h
> @@ -2244,6 +2244,12 @@ enum rt2800_eeprom_word {
> EEPROM_TSSI_BOUND_A5,
> EEPROM_TXPOWER_BYRATE,
> EEPROM_BBP_START,
> +
> + /* IDs for extended EEPROM format used by three-chain devices */
> + EEPROM_EXT_LNA2,
> + EEPROM_EXT_TXPOWER_BG3,
> + EEPROM_EXT_TXPOWER_A3,
> +
> /* New values must be added before this */
> EEPROM_WORD_COUNT
> };
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 41a34de4a..d325ca2 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -261,6 +261,48 @@ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
> [EEPROM_BBP_START] = 0x0078,
> };
>
> +static const unsigned int rt2800_eeprom_map_ext[EEPROM_WORD_COUNT] = {
> + [EEPROM_CHIP_ID] = 0x0000,
> + [EEPROM_VERSION] = 0x0001,
> + [EEPROM_MAC_ADDR_0] = 0x0002,
> + [EEPROM_MAC_ADDR_1] = 0x0003,
> + [EEPROM_MAC_ADDR_2] = 0x0004,
> + [EEPROM_NIC_CONF0] = 0x001a,
> + [EEPROM_NIC_CONF1] = 0x001b,
> + [EEPROM_NIC_CONF2] = 0x001c,
> + [EEPROM_EIRP_MAX_TX_POWER] = 0x0020,
> + [EEPROM_FREQ] = 0x0022,
> + [EEPROM_LED_AG_CONF] = 0x0023,
> + [EEPROM_LED_ACT_CONF] = 0x0024,
> + [EEPROM_LED_POLARITY] = 0x0025,
> + [EEPROM_LNA] = 0x0026,
> + [EEPROM_EXT_LNA2] = 0x0027,
> + [EEPROM_RSSI_BG] = 0x0028,
> + [EEPROM_TXPOWER_DELTA] = 0x0028, /* Overlaps with RSSI_BG */
> + [EEPROM_RSSI_BG2] = 0x0029,
> + [EEPROM_TXMIXER_GAIN_BG] = 0x0029, /* Overlaps with RSSI_BG2 */
> + [EEPROM_RSSI_A] = 0x002a,
> + [EEPROM_RSSI_A2] = 0x002b,
> + [EEPROM_TXMIXER_GAIN_A] = 0x002b, /* Overlaps with RSSI_A2 */
> + [EEPROM_TXPOWER_BG1] = 0x0030,
> + [EEPROM_TXPOWER_BG2] = 0x0037,
> + [EEPROM_EXT_TXPOWER_BG3] = 0x003e,
> + [EEPROM_TSSI_BOUND_BG1] = 0x0045,
> + [EEPROM_TSSI_BOUND_BG2] = 0x0046,
> + [EEPROM_TSSI_BOUND_BG3] = 0x0047,
> + [EEPROM_TSSI_BOUND_BG4] = 0x0048,
> + [EEPROM_TSSI_BOUND_BG5] = 0x0049,
> + [EEPROM_TXPOWER_A1] = 0x004b,
> + [EEPROM_TXPOWER_A2] = 0x0065,
> + [EEPROM_EXT_TXPOWER_A3] = 0x007f,
> + [EEPROM_TSSI_BOUND_A1] = 0x009a,
> + [EEPROM_TSSI_BOUND_A2] = 0x009b,
> + [EEPROM_TSSI_BOUND_A3] = 0x009c,
> + [EEPROM_TSSI_BOUND_A4] = 0x009d,
> + [EEPROM_TSSI_BOUND_A5] = 0x009e,
> + [EEPROM_TXPOWER_BYRATE] = 0x00a0,
> +};
> +
> static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
> const enum rt2800_eeprom_word word)
> {
> @@ -272,7 +314,11 @@ static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
> wiphy_name(rt2x00dev->hw->wiphy), word))
> return 0;
>
> - map = rt2800_eeprom_map;
> + if (rt2x00_rt(rt2x00dev, RT3593))
> + map = rt2800_eeprom_map_ext;
> + else
> + map = rt2800_eeprom_map;
> +
> index = map[word];
>
> /* Index 0 is valid only for EEPROM_CHIP_ID.
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
---
Gertjan
^ permalink raw reply
* Re: [PATCH v2 4/5] rt2x00: rt2800lib: introduce rt2800_eeprom_word_index helper
From: Gertjan van Wingerde @ 2013-07-08 10:04 UTC (permalink / raw)
To: Gabor Juhos
Cc: John Linville, linux-wireless@vger.kernel.org, rt2x00 Users List
In-Reply-To: <1373275556-6482-5-git-send-email-juhosg@openwrt.org>
On Mon, Jul 8, 2013 at 11:25 AM, Gabor Juhos <juhosg@openwrt.org> wrote:
> Instead of assign the offset value to the
> enum directly use a new helper function to
> convert a rt2800_eeprom_word enum into an
> index of the rt2x00_dev->eeprom array.
>
> The patch does not change the existing
> behaviour, but makes it possible to add
> support for three-chain devices which are
> using a different EEPROM layout.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
> Changes since v1:
> - use WARN_ONCE and remove the rt2x00_warn calls
> ---
> drivers/net/wireless/rt2x00/rt2800.h | 76 ++++++++++++++-------------
> drivers/net/wireless/rt2x00/rt2800lib.c | 87 +++++++++++++++++++++++++++++--
> 2 files changed, 122 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
> index 0647039..bc5c695 100644
> --- a/drivers/net/wireless/rt2x00/rt2800.h
> +++ b/drivers/net/wireless/rt2x00/rt2800.h
> @@ -2207,43 +2207,45 @@ struct mac_iveiv_entry {
> */
>
> enum rt2800_eeprom_word {
> - EEPROM_CHIP_ID = 0x0000,
> - EEPROM_VERSION = 0x0001,
> - EEPROM_MAC_ADDR_0 = 0x0002,
> - EEPROM_MAC_ADDR_1 = 0x0003,
> - EEPROM_MAC_ADDR_2 = 0x0004,
> - EEPROM_NIC_CONF0 = 0x001a,
> - EEPROM_NIC_CONF1 = 0x001b,
> - EEPROM_FREQ = 0x001d,
> - EEPROM_LED_AG_CONF = 0x001e,
> - EEPROM_LED_ACT_CONF = 0x001f,
> - EEPROM_LED_POLARITY = 0x0020,
> - EEPROM_NIC_CONF2 = 0x0021,
> - EEPROM_LNA = 0x0022,
> - EEPROM_RSSI_BG = 0x0023,
> - EEPROM_RSSI_BG2 = 0x0024,
> - EEPROM_TXMIXER_GAIN_BG = 0x0024, /* overlaps with RSSI_BG2 */
> - EEPROM_RSSI_A = 0x0025,
> - EEPROM_RSSI_A2 = 0x0026,
> - EEPROM_TXMIXER_GAIN_A = 0x0026, /* overlaps with RSSI_A2 */
> - EEPROM_EIRP_MAX_TX_POWER = 0x0027,
> - EEPROM_TXPOWER_DELTA = 0x0028,
> - EEPROM_TXPOWER_BG1 = 0x0029,
> - EEPROM_TXPOWER_BG2 = 0x0030,
> - EEPROM_TSSI_BOUND_BG1 = 0x0037,
> - EEPROM_TSSI_BOUND_BG2 = 0x0038,
> - EEPROM_TSSI_BOUND_BG3 = 0x0039,
> - EEPROM_TSSI_BOUND_BG4 = 0x003a,
> - EEPROM_TSSI_BOUND_BG5 = 0x003b,
> - EEPROM_TXPOWER_A1 = 0x003c,
> - EEPROM_TXPOWER_A2 = 0x0053,
> - EEPROM_TSSI_BOUND_A1 = 0x006a,
> - EEPROM_TSSI_BOUND_A2 = 0x006b,
> - EEPROM_TSSI_BOUND_A3 = 0x006c,
> - EEPROM_TSSI_BOUND_A4 = 0x006d,
> - EEPROM_TSSI_BOUND_A5 = 0x006e,
> - EEPROM_TXPOWER_BYRATE = 0x006f,
> - EEPROM_BBP_START = 0x0078,
> + EEPROM_CHIP_ID = 0,
> + EEPROM_VERSION,
> + EEPROM_MAC_ADDR_0,
> + EEPROM_MAC_ADDR_1,
> + EEPROM_MAC_ADDR_2,
> + EEPROM_NIC_CONF0,
> + EEPROM_NIC_CONF1,
> + EEPROM_FREQ,
> + EEPROM_LED_AG_CONF,
> + EEPROM_LED_ACT_CONF,
> + EEPROM_LED_POLARITY,
> + EEPROM_NIC_CONF2,
> + EEPROM_LNA,
> + EEPROM_RSSI_BG,
> + EEPROM_RSSI_BG2,
> + EEPROM_TXMIXER_GAIN_BG,
> + EEPROM_RSSI_A,
> + EEPROM_RSSI_A2,
> + EEPROM_TXMIXER_GAIN_A,
> + EEPROM_EIRP_MAX_TX_POWER,
> + EEPROM_TXPOWER_DELTA,
> + EEPROM_TXPOWER_BG1,
> + EEPROM_TXPOWER_BG2,
> + EEPROM_TSSI_BOUND_BG1,
> + EEPROM_TSSI_BOUND_BG2,
> + EEPROM_TSSI_BOUND_BG3,
> + EEPROM_TSSI_BOUND_BG4,
> + EEPROM_TSSI_BOUND_BG5,
> + EEPROM_TXPOWER_A1,
> + EEPROM_TXPOWER_A2,
> + EEPROM_TSSI_BOUND_A1,
> + EEPROM_TSSI_BOUND_A2,
> + EEPROM_TSSI_BOUND_A3,
> + EEPROM_TSSI_BOUND_A4,
> + EEPROM_TSSI_BOUND_A5,
> + EEPROM_TXPOWER_BYRATE,
> + EEPROM_BBP_START,
> + /* New values must be added before this */
> + EEPROM_WORD_COUNT
> };
>
> /*
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index b59772a..41a34de4a 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -221,22 +221,98 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
> mutex_unlock(&rt2x00dev->csr_mutex);
> }
>
> +static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
> + [EEPROM_CHIP_ID] = 0x0000,
> + [EEPROM_VERSION] = 0x0001,
> + [EEPROM_MAC_ADDR_0] = 0x0002,
> + [EEPROM_MAC_ADDR_1] = 0x0003,
> + [EEPROM_MAC_ADDR_2] = 0x0004,
> + [EEPROM_NIC_CONF0] = 0x001a,
> + [EEPROM_NIC_CONF1] = 0x001b,
> + [EEPROM_FREQ] = 0x001d,
> + [EEPROM_LED_AG_CONF] = 0x001e,
> + [EEPROM_LED_ACT_CONF] = 0x001f,
> + [EEPROM_LED_POLARITY] = 0x0020,
> + [EEPROM_NIC_CONF2] = 0x0021,
> + [EEPROM_LNA] = 0x0022,
> + [EEPROM_RSSI_BG] = 0x0023,
> + [EEPROM_RSSI_BG2] = 0x0024,
> + [EEPROM_TXMIXER_GAIN_BG] = 0x0024, /* overlaps with RSSI_BG2 */
> + [EEPROM_RSSI_A] = 0x0025,
> + [EEPROM_RSSI_A2] = 0x0026,
> + [EEPROM_TXMIXER_GAIN_A] = 0x0026, /* overlaps with RSSI_A2 */
> + [EEPROM_EIRP_MAX_TX_POWER] = 0x0027,
> + [EEPROM_TXPOWER_DELTA] = 0x0028,
> + [EEPROM_TXPOWER_BG1] = 0x0029,
> + [EEPROM_TXPOWER_BG2] = 0x0030,
> + [EEPROM_TSSI_BOUND_BG1] = 0x0037,
> + [EEPROM_TSSI_BOUND_BG2] = 0x0038,
> + [EEPROM_TSSI_BOUND_BG3] = 0x0039,
> + [EEPROM_TSSI_BOUND_BG4] = 0x003a,
> + [EEPROM_TSSI_BOUND_BG5] = 0x003b,
> + [EEPROM_TXPOWER_A1] = 0x003c,
> + [EEPROM_TXPOWER_A2] = 0x0053,
> + [EEPROM_TSSI_BOUND_A1] = 0x006a,
> + [EEPROM_TSSI_BOUND_A2] = 0x006b,
> + [EEPROM_TSSI_BOUND_A3] = 0x006c,
> + [EEPROM_TSSI_BOUND_A4] = 0x006d,
> + [EEPROM_TSSI_BOUND_A5] = 0x006e,
> + [EEPROM_TXPOWER_BYRATE] = 0x006f,
> + [EEPROM_BBP_START] = 0x0078,
> +};
> +
> +static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
> + const enum rt2800_eeprom_word word)
> +{
> + const unsigned int *map;
> + unsigned int index;
> +
> + if (WARN_ONCE(word >= EEPROM_WORD_COUNT,
> + "%s: invalid EEPROM word %d\n",
> + wiphy_name(rt2x00dev->hw->wiphy), word))
> + return 0;
> +
> + map = rt2800_eeprom_map;
> + index = map[word];
> +
> + /* Index 0 is valid only for EEPROM_CHIP_ID.
> + * Otherwise it means that the offset of the
> + * given word is not initialized in the map,
> + * or that the field is not usable on the
> + * actual chipset.
> + */
> + WARN_ONCE(word != EEPROM_CHIP_ID && index == 0,
> + "%s: invalid access of EEPROM word %d\n",
> + wiphy_name(rt2x00dev->hw->wiphy), word);
> +
> + return index;
> +}
> +
> static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
> const enum rt2800_eeprom_word word)
> {
> - return rt2x00_eeprom_addr(rt2x00dev, word);
> + unsigned int index;
> +
> + index = rt2800_eeprom_word_index(rt2x00dev, word);
> + return rt2x00_eeprom_addr(rt2x00dev, index);
> }
>
> static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
> const enum rt2800_eeprom_word word, u16 *data)
> {
> - rt2x00_eeprom_read(rt2x00dev, word, data);
> + unsigned int index;
> +
> + index = rt2800_eeprom_word_index(rt2x00dev, word);
> + rt2x00_eeprom_read(rt2x00dev, index, data);
> }
>
> static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
> const enum rt2800_eeprom_word word, u16 data)
> {
> - rt2x00_eeprom_write(rt2x00dev, word, data);
> + unsigned int index;
> +
> + index = rt2800_eeprom_word_index(rt2x00dev, word);
> + rt2x00_eeprom_write(rt2x00dev, index, data);
> }
>
> static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
> @@ -244,7 +320,10 @@ static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
> unsigned int offset,
> u16 *data)
> {
> - rt2x00_eeprom_read(rt2x00dev, array + offset, data);
> + unsigned int index;
> +
> + index = rt2800_eeprom_word_index(rt2x00dev, array);
> + rt2x00_eeprom_read(rt2x00dev, index + offset, data);
> }
>
> static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
---
Gertjan
^ permalink raw reply
* Re: [PATCH 3/3] [RFC] cfg80211: Enable GO operation on additional channels
From: Jouni Malinen @ 2013-07-08 10:04 UTC (permalink / raw)
To: Ilan Peer; +Cc: linux-wireless, mcgrof, David Spinadel
In-Reply-To: <1372768095-26053-4-git-send-email-ilan.peer@intel.com>
On Tue, Jul 02, 2013 at 03:28:15PM +0300, Ilan Peer wrote:
> Allow GO operation on a channel marked with
> IEEE80211_CHAN_INDOOR_ONLY or IEEE80211_CHAN_GO_CONCURRENT
> iff there is an active station interface that is associated to
> an AP operating on this channel.
>
> Note that this is a permissive approach to the FCC definitions,
> that require a clear assessment that either the platform device
> is an indoor device, or the device operating the AP is an indoor
> device, i.e., AC powered.
> It is assumed that these restrictions are enforced by user space.
The introduction in 0/3 mentioned DFS, but I did not see it being
addressed in any of the actual changes. Is this only for indoors vs.
outdoors?
> Furthermore, it is assumed, that if the conditions that allowed for
> the operation of the GO on such a channel change, it is the
> responsibility of user space to evacuate the GO from the channel.
Do you have plans or changes to address this? I'd assume wpa_supplicant
could stop the group on channel list changes, but I don't think it does
that currently.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [PATCH v2 3/5] rt2x00: rt2800lib: introduce rt2800_eeprom_read_from_array helper
From: Gertjan van Wingerde @ 2013-07-08 10:02 UTC (permalink / raw)
To: Gabor Juhos
Cc: John Linville, linux-wireless@vger.kernel.org, rt2x00 Users List
In-Reply-To: <1373275556-6482-4-git-send-email-juhosg@openwrt.org>
On Mon, Jul 8, 2013 at 11:25 AM, Gabor Juhos <juhosg@openwrt.org> wrote:
> Add a new helper function and use that for reading
> single elements of various arrays in the EEPROM.
>
> The patch does not change the current behaviour,
> but it allows to use sequential values for the
> rt2800_eeprom_word enums. The conversion will be
> implemented in a subsequent change.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
> Changes since v1: ---
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 23 ++++++++++++++++-------
> 1 file changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 522f0b1..b59772a 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -239,6 +239,14 @@ static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
> rt2x00_eeprom_write(rt2x00dev, word, data);
> }
>
> +static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
> + const enum rt2800_eeprom_word array,
> + unsigned int offset,
> + u16 *data)
> +{
> + rt2x00_eeprom_read(rt2x00dev, array + offset, data);
> +}
> +
> static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
> {
> u32 reg;
> @@ -2995,8 +3003,8 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
> * .11b data rate need add additional 4dbm
> * when calculating eirp txpower.
> */
> - rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
> - &eeprom);
> + rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
> + 1, &eeprom);
> criterion = rt2x00_get_field16(eeprom,
> EEPROM_TXPOWER_BYRATE_RATE0);
>
> @@ -3101,8 +3109,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
> rt2800_register_read(rt2x00dev, offset, ®);
>
> /* read the next four txpower values */
> - rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
> - &eeprom);
> + rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
> + i, &eeprom);
>
> is_rate_b = i ? 0 : 1;
> /*
> @@ -3150,8 +3158,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
> rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower);
>
> /* read the next four txpower values */
> - rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
> - &eeprom);
> + rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
> + i + 1, &eeprom);
>
> is_rate_b = 0;
> /*
> @@ -4579,7 +4587,8 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
> }
>
> for (i = 0; i < EEPROM_BBP_SIZE; i++) {
> - rt2800_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
> + rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_BBP_START, i,
> + &eeprom);
>
> if (eeprom != 0xffff && eeprom != 0x0000) {
> reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
---
Gertjan
^ permalink raw reply
* Re: [PATCH v2 2/5] rt2x00: rt2800lib: introduce local EEPROM access functions
From: Gertjan van Wingerde @ 2013-07-08 10:00 UTC (permalink / raw)
To: Gabor Juhos
Cc: John Linville, linux-wireless@vger.kernel.org, rt2x00 Users List
In-Reply-To: <1373275556-6482-3-git-send-email-juhosg@openwrt.org>
On Mon, Jul 8, 2013 at 11:25 AM, Gabor Juhos <juhosg@openwrt.org> wrote:
> The patch adds rt2800 specific functions for
> EEPROM data access and changes the code to use
> these instead of the generic rt2x00_eeprom_*
> variants.
>
> To avoid functional changes, the new functions
> are wrappers around the corresponding generic
> rt2x00_eeprom_* routines for now. Functional
> changes will be implemented in additional patches.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
> Changes since v1: ---
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 165 ++++++++++++++++++-------------
> 1 file changed, 95 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 1f80ea5..522f0b1 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -221,6 +221,24 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
> mutex_unlock(&rt2x00dev->csr_mutex);
> }
>
> +static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
> + const enum rt2800_eeprom_word word)
> +{
> + return rt2x00_eeprom_addr(rt2x00dev, word);
> +}
> +
> +static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
> + const enum rt2800_eeprom_word word, u16 *data)
> +{
> + rt2x00_eeprom_read(rt2x00dev, word, data);
> +}
> +
> +static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
> + const enum rt2800_eeprom_word word, u16 data)
> +{
> + rt2x00_eeprom_write(rt2x00dev, word, data);
> +}
> +
> static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
> {
> u32 reg;
> @@ -609,16 +627,16 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
> u8 offset2;
>
> if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
> offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
> offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
> offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2);
> } else {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
> offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0);
> offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1);
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
> offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2);
> }
>
> @@ -890,6 +908,9 @@ const struct rt2x00debug rt2800_rt2x00debug = {
> .word_count = CSR_REG_SIZE / sizeof(u32),
> },
> .eeprom = {
> + /* NOTE: The local EEPROM access functions can't
> + * be used here, use the generic versions instead.
> + */
> .read = rt2x00_eeprom_read,
> .write = rt2x00_eeprom_write,
> .word_base = EEPROM_BASE,
> @@ -1547,7 +1568,7 @@ static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
> led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
> if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
> led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
> led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
> if (led_ctrl == 0 || led_ctrl > 0x40) {
> rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode);
> @@ -1622,7 +1643,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
> rt2x00_rt(rt2x00dev, RT3090) ||
> rt2x00_rt(rt2x00dev, RT3352) ||
> rt2x00_rt(rt2x00dev, RT3390)) {
> - rt2x00_eeprom_read(rt2x00dev,
> + rt2800_eeprom_read(rt2x00dev,
> EEPROM_NIC_CONF1, &eeprom);
> if (rt2x00_get_field16(eeprom,
> EEPROM_NIC_CONF1_ANT_DIVERSITY))
> @@ -1659,16 +1680,16 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
> short lna_gain;
>
> if (libconf->rf.channel <= 14) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
> lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
> } else if (libconf->rf.channel <= 64) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
> lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
> } else if (libconf->rf.channel <= 128) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
> lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
> } else {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
> lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
> }
>
> @@ -2798,62 +2819,62 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
> * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
> */
> if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
> tssi_bounds[0] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG1_MINUS4);
> tssi_bounds[1] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG1_MINUS3);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
> tssi_bounds[2] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG2_MINUS2);
> tssi_bounds[3] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG2_MINUS1);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
> tssi_bounds[4] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG3_REF);
> tssi_bounds[5] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG3_PLUS1);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
> tssi_bounds[6] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG4_PLUS2);
> tssi_bounds[7] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG4_PLUS3);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
> tssi_bounds[8] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG5_PLUS4);
>
> step = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_BG5_AGC_STEP);
> } else {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
> tssi_bounds[0] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A1_MINUS4);
> tssi_bounds[1] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A1_MINUS3);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
> tssi_bounds[2] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A2_MINUS2);
> tssi_bounds[3] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A2_MINUS1);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
> tssi_bounds[4] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A3_REF);
> tssi_bounds[5] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A3_PLUS1);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
> tssi_bounds[6] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A4_PLUS2);
> tssi_bounds[7] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A4_PLUS3);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
> tssi_bounds[8] = rt2x00_get_field16(eeprom,
> EEPROM_TSSI_BOUND_A5_PLUS4);
>
> @@ -2899,7 +2920,7 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
> u8 comp_type;
> int comp_value = 0;
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
>
> /*
> * HT40 compensation not required.
> @@ -2974,12 +2995,12 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
> * .11b data rate need add additional 4dbm
> * when calculating eirp txpower.
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
> &eeprom);
> criterion = rt2x00_get_field16(eeprom,
> EEPROM_TXPOWER_BYRATE_RATE0);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
> + rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
> &eeprom);
>
> if (band == IEEE80211_BAND_2GHZ)
> @@ -3080,7 +3101,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
> rt2800_register_read(rt2x00dev, offset, ®);
>
> /* read the next four txpower values */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
> &eeprom);
>
> is_rate_b = i ? 0 : 1;
> @@ -3129,7 +3150,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
> rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower);
>
> /* read the next four txpower values */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
> &eeprom);
>
> is_rate_b = 0;
> @@ -3528,7 +3549,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
> if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
> rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
> rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
> + &eeprom);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
> rt2800_register_write(rt2x00dev, TX_SW_CFG2,
> 0x0000002c);
> @@ -3989,7 +4011,7 @@ static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
> u8 value;
>
> rt2800_bbp_read(rt2x00dev, 138, &value);
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
> value |= 0x20;
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
> @@ -4402,7 +4424,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
>
> rt2800_disable_unused_dac_adc(rt2x00dev);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> div_mode = rt2x00_get_field16(eeprom,
> EEPROM_NIC_CONF1_ANT_DIVERSITY);
> ant = (div_mode == 3) ? 1 : 0;
> @@ -4488,7 +4510,7 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
>
> rt2800_bbp4_mac_if_ctrl(rt2x00dev);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
> ant = (div_mode == 3) ? 1 : 0;
> rt2800_bbp_read(rt2x00dev, 152, &value);
> @@ -4557,7 +4579,7 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
> }
>
> for (i = 0; i < EEPROM_BBP_SIZE; i++) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
>
> if (eeprom != 0xffff && eeprom != 0x0000) {
> reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
> @@ -4728,7 +4750,7 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev)
> if (rt2x00_rt(rt2x00dev, RT3090)) {
> /* Turn off unused DAC1 and ADC1 to reduce power consumption */
> rt2800_bbp_read(rt2x00dev, 138, &bbp);
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
> rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
> @@ -4778,7 +4800,7 @@ static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
>
> /* Turn off unused DAC1 and ADC1 to reduce power consumption */
> rt2800_bbp_read(rt2x00dev, 138, ®);
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
> rt2x00_set_field8(®, BBP138_RX_ADC1, 0);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
> @@ -4884,7 +4906,8 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev)
> rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
> if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
> rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
> + &eeprom);
> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
> rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3);
> else
> @@ -5456,15 +5479,15 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
> /*
> * Initialize LED control
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
> rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
> word & 0xff, (word >> 8) & 0xff);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
> rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
> word & 0xff, (word >> 8) & 0xff);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
> rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
> word & 0xff, (word >> 8) & 0xff);
>
> @@ -5578,18 +5601,18 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> /*
> * Start validation of the data that has been read.
> */
> - mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
> + mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
> if (!is_valid_ether_addr(mac)) {
> eth_random_addr(mac);
> rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
> }
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
> if (word == 0xffff) {
> rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
> rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
> rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
> } else if (rt2x00_rt(rt2x00dev, RT2860) ||
> rt2x00_rt(rt2x00dev, RT2872)) {
> @@ -5598,10 +5621,10 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> */
> if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
> rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> }
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
> if (word == 0xffff) {
> rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
> rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
> @@ -5618,24 +5641,24 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
> rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
> rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
> rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);
> }
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
> if ((word & 0x00ff) == 0x00ff) {
> rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
> rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word);
> }
> if ((word & 0xff00) == 0xff00) {
> rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
> LED_MODE_TXRX_ACTIVITY);
> rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
> rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word);
> }
>
> @@ -5644,17 +5667,17 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> * lna0 as correct value. Note that EEPROM_LNA
> * is never validated.
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
> default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
> if ((word & 0x00ff) != 0x00ff) {
> drv_data->txmixer_gain_24g =
> rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
> @@ -5662,16 +5685,16 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> drv_data->txmixer_gain_24g = 0;
> }
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
> if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
> rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
> rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
> default_lna_gain);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
> if ((word & 0x00ff) != 0x00ff) {
> drv_data->txmixer_gain_5g =
> rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
> @@ -5679,21 +5702,21 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> drv_data->txmixer_gain_5g = 0;
> }
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
> if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
> rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
> if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
> rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
> rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
> default_lna_gain);
> - rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
> + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
>
> return 0;
> }
> @@ -5707,7 +5730,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> /*
> * Read EEPROM word for configuration.
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
>
> /*
> * Identify RF chipset by EEPROM value
> @@ -5717,7 +5740,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> if (rt2x00_rt(rt2x00dev, RT3290) ||
> rt2x00_rt(rt2x00dev, RT5390) ||
> rt2x00_rt(rt2x00dev, RT5392))
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
> else
> rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
>
> @@ -5757,7 +5780,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> rt2x00dev->default_ant.rx_chain_num =
> rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
>
> if (rt2x00_rt(rt2x00dev, RT3070) ||
> rt2x00_rt(rt2x00dev, RT3090) ||
> @@ -5810,7 +5833,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> /*
> * Read frequency offset and RF programming sequence.
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
> rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
>
> /*
> @@ -5827,7 +5850,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> /*
> * Check if support EIRP tx power limit feature.
> */
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
>
> if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
> EIRP_MAX_TX_POWER_LIMIT)
> @@ -6148,7 +6171,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>
> SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
> SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
> - rt2x00_eeprom_addr(rt2x00dev,
> + rt2800_eeprom_addr(rt2x00dev,
> EEPROM_MAC_ADDR_0));
>
> /*
> @@ -6164,7 +6187,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> rt2x00dev->hw->max_report_rates = 7;
> rt2x00dev->hw->max_rate_tries = 1;
>
> - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
> + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
>
> /*
> * Initialize hw_mode information.
> @@ -6264,8 +6287,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>
> spec->channels_info = info;
>
> - default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
> - default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
> + default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
> + default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
>
> for (i = 0; i < 14; i++) {
> info[i].default_power1 = default_power1[i];
> @@ -6273,8 +6296,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> }
>
> if (spec->num_channels > 14) {
> - default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
> - default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
> + default_power1 = rt2800_eeprom_addr(rt2x00dev,
> + EEPROM_TXPOWER_A1);
> + default_power2 = rt2800_eeprom_addr(rt2x00dev,
> + EEPROM_TXPOWER_A2);
>
> for (i = 14; i < spec->num_channels; i++) {
> info[i].default_power1 = default_power1[i - 14];
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
---
Gertjan
^ permalink raw reply
* Re: [PATCH v2 1/5] rt2x00: rt2800lib: introduce rt2800_eeprom_word enum
From: Gertjan van Wingerde @ 2013-07-08 9:59 UTC (permalink / raw)
To: Gabor Juhos
Cc: John Linville, linux-wireless@vger.kernel.org, rt2x00 Users List
In-Reply-To: <1373275556-6482-2-git-send-email-juhosg@openwrt.org>
On Mon, Jul 8, 2013 at 11:25 AM, Gabor Juhos <juhosg@openwrt.org> wrote:
> The patch converts the EEPROM_* word address defines
> into new enum values. The new enum type will be used
> by new functions which will be introduced in subsequent
> changes.
>
> The patch contains no functional changes.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
> Changes since v1: ---
> ---
> drivers/net/wireless/rt2x00/rt2800.h | 79 +++++++++++++++++-----------------
> 1 file changed, 39 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
> index d78c495..0647039 100644
> --- a/drivers/net/wireless/rt2x00/rt2800.h
> +++ b/drivers/net/wireless/rt2x00/rt2800.h
> @@ -2206,28 +2206,59 @@ struct mac_iveiv_entry {
> * The wordsize of the EEPROM is 16 bits.
> */
>
> -/*
> - * Chip ID
> - */
> -#define EEPROM_CHIP_ID 0x0000
> +enum rt2800_eeprom_word {
> + EEPROM_CHIP_ID = 0x0000,
> + EEPROM_VERSION = 0x0001,
> + EEPROM_MAC_ADDR_0 = 0x0002,
> + EEPROM_MAC_ADDR_1 = 0x0003,
> + EEPROM_MAC_ADDR_2 = 0x0004,
> + EEPROM_NIC_CONF0 = 0x001a,
> + EEPROM_NIC_CONF1 = 0x001b,
> + EEPROM_FREQ = 0x001d,
> + EEPROM_LED_AG_CONF = 0x001e,
> + EEPROM_LED_ACT_CONF = 0x001f,
> + EEPROM_LED_POLARITY = 0x0020,
> + EEPROM_NIC_CONF2 = 0x0021,
> + EEPROM_LNA = 0x0022,
> + EEPROM_RSSI_BG = 0x0023,
> + EEPROM_RSSI_BG2 = 0x0024,
> + EEPROM_TXMIXER_GAIN_BG = 0x0024, /* overlaps with RSSI_BG2 */
> + EEPROM_RSSI_A = 0x0025,
> + EEPROM_RSSI_A2 = 0x0026,
> + EEPROM_TXMIXER_GAIN_A = 0x0026, /* overlaps with RSSI_A2 */
> + EEPROM_EIRP_MAX_TX_POWER = 0x0027,
> + EEPROM_TXPOWER_DELTA = 0x0028,
> + EEPROM_TXPOWER_BG1 = 0x0029,
> + EEPROM_TXPOWER_BG2 = 0x0030,
> + EEPROM_TSSI_BOUND_BG1 = 0x0037,
> + EEPROM_TSSI_BOUND_BG2 = 0x0038,
> + EEPROM_TSSI_BOUND_BG3 = 0x0039,
> + EEPROM_TSSI_BOUND_BG4 = 0x003a,
> + EEPROM_TSSI_BOUND_BG5 = 0x003b,
> + EEPROM_TXPOWER_A1 = 0x003c,
> + EEPROM_TXPOWER_A2 = 0x0053,
> + EEPROM_TSSI_BOUND_A1 = 0x006a,
> + EEPROM_TSSI_BOUND_A2 = 0x006b,
> + EEPROM_TSSI_BOUND_A3 = 0x006c,
> + EEPROM_TSSI_BOUND_A4 = 0x006d,
> + EEPROM_TSSI_BOUND_A5 = 0x006e,
> + EEPROM_TXPOWER_BYRATE = 0x006f,
> + EEPROM_BBP_START = 0x0078,
> +};
>
> /*
> * EEPROM Version
> */
> -#define EEPROM_VERSION 0x0001
> #define EEPROM_VERSION_FAE FIELD16(0x00ff)
> #define EEPROM_VERSION_VERSION FIELD16(0xff00)
>
> /*
> * HW MAC address.
> */
> -#define EEPROM_MAC_ADDR_0 0x0002
> #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff)
> #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00)
> -#define EEPROM_MAC_ADDR_1 0x0003
> #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff)
> #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00)
> -#define EEPROM_MAC_ADDR_2 0x0004
> #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff)
> #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
>
> @@ -2237,7 +2268,6 @@ struct mac_iveiv_entry {
> * TXPATH: 1: 1T, 2: 2T, 3: 3T
> * RF_TYPE: RFIC type
> */
> -#define EEPROM_NIC_CONF0 0x001a
> #define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
> #define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
> #define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
> @@ -2261,7 +2291,6 @@ struct mac_iveiv_entry {
> * BT_COEXIST: 0: disable, 1: enable
> * DAC_TEST: 0: disable, 1: enable
> */
> -#define EEPROM_NIC_CONF1 0x001b
> #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
> #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
> #define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
> @@ -2281,7 +2310,6 @@ struct mac_iveiv_entry {
> /*
> * EEPROM frequency
> */
> -#define EEPROM_FREQ 0x001d
> #define EEPROM_FREQ_OFFSET FIELD16(0x00ff)
> #define EEPROM_FREQ_LED_MODE FIELD16(0x7f00)
> #define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000)
> @@ -2298,9 +2326,6 @@ struct mac_iveiv_entry {
> * POLARITY_GPIO_4: Polarity GPIO4 setting.
> * LED_MODE: Led mode.
> */
> -#define EEPROM_LED_AG_CONF 0x001e
> -#define EEPROM_LED_ACT_CONF 0x001f
> -#define EEPROM_LED_POLARITY 0x0020
> #define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
> #define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
> #define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
> @@ -2317,7 +2342,6 @@ struct mac_iveiv_entry {
> * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
> * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
> */
> -#define EEPROM_NIC_CONF2 0x0021
> #define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
> #define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
> #define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
> @@ -2325,54 +2349,46 @@ struct mac_iveiv_entry {
> /*
> * EEPROM LNA
> */
> -#define EEPROM_LNA 0x0022
> #define EEPROM_LNA_BG FIELD16(0x00ff)
> #define EEPROM_LNA_A0 FIELD16(0xff00)
>
> /*
> * EEPROM RSSI BG offset
> */
> -#define EEPROM_RSSI_BG 0x0023
> #define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff)
> #define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00)
>
> /*
> * EEPROM RSSI BG2 offset
> */
> -#define EEPROM_RSSI_BG2 0x0024
> #define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff)
> #define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
>
> /*
> * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
> */
> -#define EEPROM_TXMIXER_GAIN_BG 0x0024
> #define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007)
>
> /*
> * EEPROM RSSI A offset
> */
> -#define EEPROM_RSSI_A 0x0025
> #define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff)
> #define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00)
>
> /*
> * EEPROM RSSI A2 offset
> */
> -#define EEPROM_RSSI_A2 0x0026
> #define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff)
> #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
>
> /*
> * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
> */
> -#define EEPROM_TXMIXER_GAIN_A 0x0026
> #define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007)
>
> /*
> * EEPROM EIRP Maximum TX power values(unit: dbm)
> */
> -#define EEPROM_EIRP_MAX_TX_POWER 0x0027
> #define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff)
> #define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00)
>
> @@ -2383,7 +2399,6 @@ struct mac_iveiv_entry {
> * TYPE: 1: Plus the delta value, 0: minus the delta value
> * ENABLE: enable tx power compensation for 40BW
> */
> -#define EEPROM_TXPOWER_DELTA 0x0028
> #define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f)
> #define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040)
> #define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080)
> @@ -2394,8 +2409,6 @@ struct mac_iveiv_entry {
> /*
> * EEPROM TXPOWER 802.11BG
> */
> -#define EEPROM_TXPOWER_BG1 0x0029
> -#define EEPROM_TXPOWER_BG2 0x0030
> #define EEPROM_TXPOWER_BG_SIZE 7
> #define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff)
> #define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
> @@ -2407,7 +2420,6 @@ struct mac_iveiv_entry {
> * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
> * reduced by (agc_step * -3)
> */
> -#define EEPROM_TSSI_BOUND_BG1 0x0037
> #define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00)
>
> @@ -2418,7 +2430,6 @@ struct mac_iveiv_entry {
> * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
> * reduced by (agc_step * -1)
> */
> -#define EEPROM_TSSI_BOUND_BG2 0x0038
> #define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00)
>
> @@ -2428,7 +2439,6 @@ struct mac_iveiv_entry {
> * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
> * increased by (agc_step * 1)
> */
> -#define EEPROM_TSSI_BOUND_BG3 0x0039
> #define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00)
>
> @@ -2439,7 +2449,6 @@ struct mac_iveiv_entry {
> * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
> * increased by (agc_step * 3)
> */
> -#define EEPROM_TSSI_BOUND_BG4 0x003a
> #define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00)
>
> @@ -2449,15 +2458,12 @@ struct mac_iveiv_entry {
> * increased by (agc_step * 4)
> * AGC_STEP: Temperature compensation step.
> */
> -#define EEPROM_TSSI_BOUND_BG5 0x003b
> #define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00)
>
> /*
> * EEPROM TXPOWER 802.11A
> */
> -#define EEPROM_TXPOWER_A1 0x003c
> -#define EEPROM_TXPOWER_A2 0x0053
> #define EEPROM_TXPOWER_A_SIZE 6
> #define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
> #define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
> @@ -2469,7 +2475,6 @@ struct mac_iveiv_entry {
> * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
> * reduced by (agc_step * -3)
> */
> -#define EEPROM_TSSI_BOUND_A1 0x006a
> #define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00)
>
> @@ -2480,7 +2485,6 @@ struct mac_iveiv_entry {
> * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
> * reduced by (agc_step * -1)
> */
> -#define EEPROM_TSSI_BOUND_A2 0x006b
> #define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00)
>
> @@ -2490,7 +2494,6 @@ struct mac_iveiv_entry {
> * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
> * increased by (agc_step * 1)
> */
> -#define EEPROM_TSSI_BOUND_A3 0x006c
> #define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00)
>
> @@ -2501,7 +2504,6 @@ struct mac_iveiv_entry {
> * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
> * increased by (agc_step * 3)
> */
> -#define EEPROM_TSSI_BOUND_A4 0x006d
> #define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00)
>
> @@ -2511,14 +2513,12 @@ struct mac_iveiv_entry {
> * increased by (agc_step * 4)
> * AGC_STEP: Temperature compensation step.
> */
> -#define EEPROM_TSSI_BOUND_A5 0x006e
> #define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff)
> #define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00)
>
> /*
> * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
> */
> -#define EEPROM_TXPOWER_BYRATE 0x006f
> #define EEPROM_TXPOWER_BYRATE_SIZE 9
>
> #define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f)
> @@ -2529,7 +2529,6 @@ struct mac_iveiv_entry {
> /*
> * EEPROM BBP.
> */
> -#define EEPROM_BBP_START 0x0078
> #define EEPROM_BBP_SIZE 16
> #define EEPROM_BBP_VALUE FIELD16(0x00ff)
> #define EEPROM_BBP_REG_ID FIELD16(0xff00)
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
---
Gertjan
^ permalink raw reply
* Re: [PATCH] brcm: add brcmfmac sdio firmware for bcm43241
From: Arend van Spriel @ 2013-07-08 9:29 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Linux Wireless, Franky Lin, David Woodhouse, Stephen Warren
In-Reply-To: <1373125142.22888.113.camel@deadeye.wl.decadent.org.uk>
On 07/06/2013 05:39 PM, Ben Hutchings wrote:
> On Thu, 2013-07-04 at 12:34 +0200, Arend van Spriel wrote:
>> On 07/04/2013 04:22 AM, Ben Hutchings wrote:
>>> On Wed, 2013-05-29 at 15:13 +0200, Arend van Spriel wrote:
> [...]
>>>> --- a/WHENCE
>>>> +++ b/WHENCE
>>>> @@ -1652,6 +1652,7 @@ Driver: brcmfmac - Broadcom 802.11n fullmac wireless LAN driver.
>>>>
>>>> File: brcm/bcm4329-fullmac-4.bin
>>>> File: brcm/brcmfmac43236b.bin
>>>> +File: brcm/brcmfmac43241.bin
>>>> File: brcm/brcmfmac4329.bin
>>>> File: brcm/brcmfmac4330.bin
>>>> File: brcm/brcmfmac4334.bin
>>> [...]
>>>
>>> Unless you're doing something very clever with macros, I don't believe
>>> you've posted any driver code that uses this file... or several of the
>>> others. The current driver in net-next (I don't know what you've sent
>>> to Nvidia) appears to request only these files:
>>
>> Hi, Ben
>>
>> Nvidia was just using the upstream brcmfmac driver. The "clever" thing
>> we are doing for the SDIO part of our brcmfmac driver is that the
>> firmware filename requested by the driver is always brcmfmac-sdio.bin.
>> We explain on wireless.kernel.org that people should link/copy the
>> firmware file for their device to brcmfmac-sdio.bin
>
> Not a great idea, but I think you recognise that now.
>
>> and get
>> brcmfmac-sdio.txt from their board supplier as it is very board specific
>> initialization data.
>
> What if someone wants to put more than one of these devices in the same
> system?
It is the same issue as the firmware.
> [...]
>>> So I think, before this patch is applied, you owe me and David patches
>>> to:
>>>
>>> 1. Add brcm/brcmfmac43143.bin, brcm/brcmfmac43242a.bin and
>>> brcm/brcmfmac-sdio.txt.
>>
>> The 43143 and 43242 bin files will be submitted, but these firmwares
>> have not yet been released. I have to wait for a green light on that.
>>
>>> 2. Rename brcm/bcm4329-fullmac-4.bin to brcm/brcmfmac-sdio.bin.
>>
>> That file is there for brcmfmac in older kernels (< v3.3) as the
>> replacement brcmfmac4329.bin does not work with brcmfmac in those older
>> kernels.
>
> OK.
>
>>> 3. Add symlinks from all the old names to the new names. (As
>>> linux-firmware should support old in-tree drivers indefinitely.)
>>
>> I will look into this to see what names were used by brcmfmac since it
>> was mainlined.
>
> As I said, all the names that have been used should be supported. So
> either provide multiple versions of the firmware or add symlinks, as
> appropriate.
Will do.
>>> and you owe linux-wireless some driver patches.
>>>
>>> linux-firmware.git is not the appropriate place to send firmware used
>>> only by out-of-tree code, and any firmware blob that has never been
>>> referenced by in-tree code is subject to removal.
>>
>> I am aware and none of the firmwares we released are for out-of-tree
>> code. We actually got feedback that using the same firmware filename for
>> multiple devices was not very user-friendly. Therefore we will get rid
>> of this quirky approach in the next kernel and the firmware files in
>> linux-firmware will be listed in brcmfmac using the MODULE_FIRMWARE() macro.
>
> Thanks for clearing this up.
>
> Please re-send the new firmware, and include the firmware version in
> WHENCE.
I will prepare patches to address item #3 above and to add the new firmware.
Thanks,
Arend
^ permalink raw reply
* Re: [rt2x00-users] [PATCH 4/5] rt2x00: rt2800lib: introduce rt2800_eeprom_word_index helper
From: Gabor Juhos @ 2013-07-08 9:26 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: John Linville, linux-wireless, users
In-Reply-To: <20130704182746.GA2061@localhost.localdomain>
Hi Stanislaw,
> On Wed, Jul 03, 2013 at 10:23:26PM +0200, Gabor Juhos wrote:
>>> I have two nit-picks, but they can be fixed later on top of your current
>>> patches.
>>>
>>>> + if (WARN_ON(word >= EEPROM_WORD_COUNT)) {
>>>> + rt2x00_warn(rt2x00dev, "invalid EEPROM word %d\n", word);
>>>> + return 0;
>>>> + }
>>>
>>> Since we take "enum rt2800_eeprom_word" as word argument, it can not
>>> have different values than already listed, so this warning is not needed.
>>
>> EEPROM_WORD_COUNT is listed in the enums and the word argument can be equal to
>> that, however it is not a valid index for the EEPROM map. Additionally, if
>> someone puts a new enum value after EEPROM_WORD_COUNT by mistake that will be an
>> invalid index as well.
>
> I do not feel that there is big chance that someone will do such
> mistakes, but yes, they are at least theoretically possible, so warning
> can stay.
>
>> My reason behind the rt2x00_warn call was that it shows the wiphy name. If you
>> are testing different devices in parallel it is good to know which one causes
>> the warning. However I can use 'wiphy_name(rt2x00dev->hw->wiphy)' to get that
>> information.
>>
>> I will send a follow-up patch which removes the rt2x00_warn calls. Do you also
>> prefer WARN_ONCE instead of WARN?
>
> I prefer WARN_ONCE variant to avoid possible spamming dmesg with lot of
> warnings.
Ok. Because the patch-set has not been integrated yet, I have sent an updated
version instead of a follow-up patch.
-Gabor
^ permalink raw reply
* [PATCH v2 4/5] rt2x00: rt2800lib: introduce rt2800_eeprom_word_index helper
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1373275556-6482-1-git-send-email-juhosg@openwrt.org>
Instead of assign the offset value to the
enum directly use a new helper function to
convert a rt2800_eeprom_word enum into an
index of the rt2x00_dev->eeprom array.
The patch does not change the existing
behaviour, but makes it possible to add
support for three-chain devices which are
using a different EEPROM layout.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1:
- use WARN_ONCE and remove the rt2x00_warn calls
---
drivers/net/wireless/rt2x00/rt2800.h | 76 ++++++++++++++-------------
drivers/net/wireless/rt2x00/rt2800lib.c | 87 +++++++++++++++++++++++++++++--
2 files changed, 122 insertions(+), 41 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 0647039..bc5c695 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2207,43 +2207,45 @@ struct mac_iveiv_entry {
*/
enum rt2800_eeprom_word {
- EEPROM_CHIP_ID = 0x0000,
- EEPROM_VERSION = 0x0001,
- EEPROM_MAC_ADDR_0 = 0x0002,
- EEPROM_MAC_ADDR_1 = 0x0003,
- EEPROM_MAC_ADDR_2 = 0x0004,
- EEPROM_NIC_CONF0 = 0x001a,
- EEPROM_NIC_CONF1 = 0x001b,
- EEPROM_FREQ = 0x001d,
- EEPROM_LED_AG_CONF = 0x001e,
- EEPROM_LED_ACT_CONF = 0x001f,
- EEPROM_LED_POLARITY = 0x0020,
- EEPROM_NIC_CONF2 = 0x0021,
- EEPROM_LNA = 0x0022,
- EEPROM_RSSI_BG = 0x0023,
- EEPROM_RSSI_BG2 = 0x0024,
- EEPROM_TXMIXER_GAIN_BG = 0x0024, /* overlaps with RSSI_BG2 */
- EEPROM_RSSI_A = 0x0025,
- EEPROM_RSSI_A2 = 0x0026,
- EEPROM_TXMIXER_GAIN_A = 0x0026, /* overlaps with RSSI_A2 */
- EEPROM_EIRP_MAX_TX_POWER = 0x0027,
- EEPROM_TXPOWER_DELTA = 0x0028,
- EEPROM_TXPOWER_BG1 = 0x0029,
- EEPROM_TXPOWER_BG2 = 0x0030,
- EEPROM_TSSI_BOUND_BG1 = 0x0037,
- EEPROM_TSSI_BOUND_BG2 = 0x0038,
- EEPROM_TSSI_BOUND_BG3 = 0x0039,
- EEPROM_TSSI_BOUND_BG4 = 0x003a,
- EEPROM_TSSI_BOUND_BG5 = 0x003b,
- EEPROM_TXPOWER_A1 = 0x003c,
- EEPROM_TXPOWER_A2 = 0x0053,
- EEPROM_TSSI_BOUND_A1 = 0x006a,
- EEPROM_TSSI_BOUND_A2 = 0x006b,
- EEPROM_TSSI_BOUND_A3 = 0x006c,
- EEPROM_TSSI_BOUND_A4 = 0x006d,
- EEPROM_TSSI_BOUND_A5 = 0x006e,
- EEPROM_TXPOWER_BYRATE = 0x006f,
- EEPROM_BBP_START = 0x0078,
+ EEPROM_CHIP_ID = 0,
+ EEPROM_VERSION,
+ EEPROM_MAC_ADDR_0,
+ EEPROM_MAC_ADDR_1,
+ EEPROM_MAC_ADDR_2,
+ EEPROM_NIC_CONF0,
+ EEPROM_NIC_CONF1,
+ EEPROM_FREQ,
+ EEPROM_LED_AG_CONF,
+ EEPROM_LED_ACT_CONF,
+ EEPROM_LED_POLARITY,
+ EEPROM_NIC_CONF2,
+ EEPROM_LNA,
+ EEPROM_RSSI_BG,
+ EEPROM_RSSI_BG2,
+ EEPROM_TXMIXER_GAIN_BG,
+ EEPROM_RSSI_A,
+ EEPROM_RSSI_A2,
+ EEPROM_TXMIXER_GAIN_A,
+ EEPROM_EIRP_MAX_TX_POWER,
+ EEPROM_TXPOWER_DELTA,
+ EEPROM_TXPOWER_BG1,
+ EEPROM_TXPOWER_BG2,
+ EEPROM_TSSI_BOUND_BG1,
+ EEPROM_TSSI_BOUND_BG2,
+ EEPROM_TSSI_BOUND_BG3,
+ EEPROM_TSSI_BOUND_BG4,
+ EEPROM_TSSI_BOUND_BG5,
+ EEPROM_TXPOWER_A1,
+ EEPROM_TXPOWER_A2,
+ EEPROM_TSSI_BOUND_A1,
+ EEPROM_TSSI_BOUND_A2,
+ EEPROM_TSSI_BOUND_A3,
+ EEPROM_TSSI_BOUND_A4,
+ EEPROM_TSSI_BOUND_A5,
+ EEPROM_TXPOWER_BYRATE,
+ EEPROM_BBP_START,
+ /* New values must be added before this */
+ EEPROM_WORD_COUNT
};
/*
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b59772a..41a34de4a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -221,22 +221,98 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
+static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
+ [EEPROM_CHIP_ID] = 0x0000,
+ [EEPROM_VERSION] = 0x0001,
+ [EEPROM_MAC_ADDR_0] = 0x0002,
+ [EEPROM_MAC_ADDR_1] = 0x0003,
+ [EEPROM_MAC_ADDR_2] = 0x0004,
+ [EEPROM_NIC_CONF0] = 0x001a,
+ [EEPROM_NIC_CONF1] = 0x001b,
+ [EEPROM_FREQ] = 0x001d,
+ [EEPROM_LED_AG_CONF] = 0x001e,
+ [EEPROM_LED_ACT_CONF] = 0x001f,
+ [EEPROM_LED_POLARITY] = 0x0020,
+ [EEPROM_NIC_CONF2] = 0x0021,
+ [EEPROM_LNA] = 0x0022,
+ [EEPROM_RSSI_BG] = 0x0023,
+ [EEPROM_RSSI_BG2] = 0x0024,
+ [EEPROM_TXMIXER_GAIN_BG] = 0x0024, /* overlaps with RSSI_BG2 */
+ [EEPROM_RSSI_A] = 0x0025,
+ [EEPROM_RSSI_A2] = 0x0026,
+ [EEPROM_TXMIXER_GAIN_A] = 0x0026, /* overlaps with RSSI_A2 */
+ [EEPROM_EIRP_MAX_TX_POWER] = 0x0027,
+ [EEPROM_TXPOWER_DELTA] = 0x0028,
+ [EEPROM_TXPOWER_BG1] = 0x0029,
+ [EEPROM_TXPOWER_BG2] = 0x0030,
+ [EEPROM_TSSI_BOUND_BG1] = 0x0037,
+ [EEPROM_TSSI_BOUND_BG2] = 0x0038,
+ [EEPROM_TSSI_BOUND_BG3] = 0x0039,
+ [EEPROM_TSSI_BOUND_BG4] = 0x003a,
+ [EEPROM_TSSI_BOUND_BG5] = 0x003b,
+ [EEPROM_TXPOWER_A1] = 0x003c,
+ [EEPROM_TXPOWER_A2] = 0x0053,
+ [EEPROM_TSSI_BOUND_A1] = 0x006a,
+ [EEPROM_TSSI_BOUND_A2] = 0x006b,
+ [EEPROM_TSSI_BOUND_A3] = 0x006c,
+ [EEPROM_TSSI_BOUND_A4] = 0x006d,
+ [EEPROM_TSSI_BOUND_A5] = 0x006e,
+ [EEPROM_TXPOWER_BYRATE] = 0x006f,
+ [EEPROM_BBP_START] = 0x0078,
+};
+
+static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
+ const enum rt2800_eeprom_word word)
+{
+ const unsigned int *map;
+ unsigned int index;
+
+ if (WARN_ONCE(word >= EEPROM_WORD_COUNT,
+ "%s: invalid EEPROM word %d\n",
+ wiphy_name(rt2x00dev->hw->wiphy), word))
+ return 0;
+
+ map = rt2800_eeprom_map;
+ index = map[word];
+
+ /* Index 0 is valid only for EEPROM_CHIP_ID.
+ * Otherwise it means that the offset of the
+ * given word is not initialized in the map,
+ * or that the field is not usable on the
+ * actual chipset.
+ */
+ WARN_ONCE(word != EEPROM_CHIP_ID && index == 0,
+ "%s: invalid access of EEPROM word %d\n",
+ wiphy_name(rt2x00dev->hw->wiphy), word);
+
+ return index;
+}
+
static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
const enum rt2800_eeprom_word word)
{
- return rt2x00_eeprom_addr(rt2x00dev, word);
+ unsigned int index;
+
+ index = rt2800_eeprom_word_index(rt2x00dev, word);
+ return rt2x00_eeprom_addr(rt2x00dev, index);
}
static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
const enum rt2800_eeprom_word word, u16 *data)
{
- rt2x00_eeprom_read(rt2x00dev, word, data);
+ unsigned int index;
+
+ index = rt2800_eeprom_word_index(rt2x00dev, word);
+ rt2x00_eeprom_read(rt2x00dev, index, data);
}
static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
const enum rt2800_eeprom_word word, u16 data)
{
- rt2x00_eeprom_write(rt2x00dev, word, data);
+ unsigned int index;
+
+ index = rt2800_eeprom_word_index(rt2x00dev, word);
+ rt2x00_eeprom_write(rt2x00dev, index, data);
}
static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
@@ -244,7 +320,10 @@ static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
unsigned int offset,
u16 *data)
{
- rt2x00_eeprom_read(rt2x00dev, array + offset, data);
+ unsigned int index;
+
+ index = rt2800_eeprom_word_index(rt2x00dev, array);
+ rt2x00_eeprom_read(rt2x00dev, index + offset, data);
}
static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
--
1.7.10
^ permalink raw reply related
* [PATCH v2 5/5] rt2x00: rt2800lib: add EEPROM map for the RT3593 chipset
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1373275556-6482-1-git-send-email-juhosg@openwrt.org>
Three-chain devices are using a different
EEPROM layout than the rest of the chipsets.
Add a new map which describes the new layout
and use that for the RT3593 chipset.
The index values has been computed from the
EEPROM_EXT_* defines, which can be found in
the 'include/chip/rt3593.h' file in the
Ralink DPO_RT5572_LinuxSTA_2.6.0.1_20120629
driver.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800.h | 6 ++++
drivers/net/wireless/rt2x00/rt2800lib.c | 48 ++++++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index bc5c695..9216834 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2244,6 +2244,12 @@ enum rt2800_eeprom_word {
EEPROM_TSSI_BOUND_A5,
EEPROM_TXPOWER_BYRATE,
EEPROM_BBP_START,
+
+ /* IDs for extended EEPROM format used by three-chain devices */
+ EEPROM_EXT_LNA2,
+ EEPROM_EXT_TXPOWER_BG3,
+ EEPROM_EXT_TXPOWER_A3,
+
/* New values must be added before this */
EEPROM_WORD_COUNT
};
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 41a34de4a..d325ca2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -261,6 +261,48 @@ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
[EEPROM_BBP_START] = 0x0078,
};
+static const unsigned int rt2800_eeprom_map_ext[EEPROM_WORD_COUNT] = {
+ [EEPROM_CHIP_ID] = 0x0000,
+ [EEPROM_VERSION] = 0x0001,
+ [EEPROM_MAC_ADDR_0] = 0x0002,
+ [EEPROM_MAC_ADDR_1] = 0x0003,
+ [EEPROM_MAC_ADDR_2] = 0x0004,
+ [EEPROM_NIC_CONF0] = 0x001a,
+ [EEPROM_NIC_CONF1] = 0x001b,
+ [EEPROM_NIC_CONF2] = 0x001c,
+ [EEPROM_EIRP_MAX_TX_POWER] = 0x0020,
+ [EEPROM_FREQ] = 0x0022,
+ [EEPROM_LED_AG_CONF] = 0x0023,
+ [EEPROM_LED_ACT_CONF] = 0x0024,
+ [EEPROM_LED_POLARITY] = 0x0025,
+ [EEPROM_LNA] = 0x0026,
+ [EEPROM_EXT_LNA2] = 0x0027,
+ [EEPROM_RSSI_BG] = 0x0028,
+ [EEPROM_TXPOWER_DELTA] = 0x0028, /* Overlaps with RSSI_BG */
+ [EEPROM_RSSI_BG2] = 0x0029,
+ [EEPROM_TXMIXER_GAIN_BG] = 0x0029, /* Overlaps with RSSI_BG2 */
+ [EEPROM_RSSI_A] = 0x002a,
+ [EEPROM_RSSI_A2] = 0x002b,
+ [EEPROM_TXMIXER_GAIN_A] = 0x002b, /* Overlaps with RSSI_A2 */
+ [EEPROM_TXPOWER_BG1] = 0x0030,
+ [EEPROM_TXPOWER_BG2] = 0x0037,
+ [EEPROM_EXT_TXPOWER_BG3] = 0x003e,
+ [EEPROM_TSSI_BOUND_BG1] = 0x0045,
+ [EEPROM_TSSI_BOUND_BG2] = 0x0046,
+ [EEPROM_TSSI_BOUND_BG3] = 0x0047,
+ [EEPROM_TSSI_BOUND_BG4] = 0x0048,
+ [EEPROM_TSSI_BOUND_BG5] = 0x0049,
+ [EEPROM_TXPOWER_A1] = 0x004b,
+ [EEPROM_TXPOWER_A2] = 0x0065,
+ [EEPROM_EXT_TXPOWER_A3] = 0x007f,
+ [EEPROM_TSSI_BOUND_A1] = 0x009a,
+ [EEPROM_TSSI_BOUND_A2] = 0x009b,
+ [EEPROM_TSSI_BOUND_A3] = 0x009c,
+ [EEPROM_TSSI_BOUND_A4] = 0x009d,
+ [EEPROM_TSSI_BOUND_A5] = 0x009e,
+ [EEPROM_TXPOWER_BYRATE] = 0x00a0,
+};
+
static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
const enum rt2800_eeprom_word word)
{
@@ -272,7 +314,11 @@ static unsigned int rt2800_eeprom_word_index(struct rt2x00_dev *rt2x00dev,
wiphy_name(rt2x00dev->hw->wiphy), word))
return 0;
- map = rt2800_eeprom_map;
+ if (rt2x00_rt(rt2x00dev, RT3593))
+ map = rt2800_eeprom_map_ext;
+ else
+ map = rt2800_eeprom_map;
+
index = map[word];
/* Index 0 is valid only for EEPROM_CHIP_ID.
--
1.7.10
^ permalink raw reply related
* [PATCH v2 2/5] rt2x00: rt2800lib: introduce local EEPROM access functions
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1373275556-6482-1-git-send-email-juhosg@openwrt.org>
The patch adds rt2800 specific functions for
EEPROM data access and changes the code to use
these instead of the generic rt2x00_eeprom_*
variants.
To avoid functional changes, the new functions
are wrappers around the corresponding generic
rt2x00_eeprom_* routines for now. Functional
changes will be implemented in additional patches.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800lib.c | 165 ++++++++++++++++++-------------
1 file changed, 95 insertions(+), 70 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1f80ea5..522f0b1 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -221,6 +221,24 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
+static void *rt2800_eeprom_addr(struct rt2x00_dev *rt2x00dev,
+ const enum rt2800_eeprom_word word)
+{
+ return rt2x00_eeprom_addr(rt2x00dev, word);
+}
+
+static void rt2800_eeprom_read(struct rt2x00_dev *rt2x00dev,
+ const enum rt2800_eeprom_word word, u16 *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, word, data);
+}
+
+static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
+ const enum rt2800_eeprom_word word, u16 data)
+{
+ rt2x00_eeprom_write(rt2x00dev, word, data);
+}
+
static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
@@ -609,16 +627,16 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
u8 offset2;
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2);
} else {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom);
offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0);
offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2);
}
@@ -890,6 +908,9 @@ const struct rt2x00debug rt2800_rt2x00debug = {
.word_count = CSR_REG_SIZE / sizeof(u32),
},
.eeprom = {
+ /* NOTE: The local EEPROM access functions can't
+ * be used here, use the generic versions instead.
+ */
.read = rt2x00_eeprom_read,
.write = rt2x00_eeprom_write,
.word_base = EEPROM_BASE,
@@ -1547,7 +1568,7 @@ static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
if (led_ctrl == 0 || led_ctrl > 0x40) {
rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode);
@@ -1622,7 +1643,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3352) ||
rt2x00_rt(rt2x00dev, RT3390)) {
- rt2x00_eeprom_read(rt2x00dev,
+ rt2800_eeprom_read(rt2x00dev,
EEPROM_NIC_CONF1, &eeprom);
if (rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_ANT_DIVERSITY))
@@ -1659,16 +1680,16 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
short lna_gain;
if (libconf->rf.channel <= 14) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
} else if (libconf->rf.channel <= 64) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
} else if (libconf->rf.channel <= 128) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
} else {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
}
@@ -2798,62 +2819,62 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
* Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
*/
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
tssi_bounds[0] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG1_MINUS4);
tssi_bounds[1] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG1_MINUS3);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
tssi_bounds[2] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG2_MINUS2);
tssi_bounds[3] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG2_MINUS1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
tssi_bounds[4] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG3_REF);
tssi_bounds[5] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG3_PLUS1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
tssi_bounds[6] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG4_PLUS2);
tssi_bounds[7] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG4_PLUS3);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
tssi_bounds[8] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG5_PLUS4);
step = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_BG5_AGC_STEP);
} else {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
tssi_bounds[0] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A1_MINUS4);
tssi_bounds[1] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A1_MINUS3);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
tssi_bounds[2] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A2_MINUS2);
tssi_bounds[3] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A2_MINUS1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
tssi_bounds[4] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A3_REF);
tssi_bounds[5] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A3_PLUS1);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
tssi_bounds[6] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A4_PLUS2);
tssi_bounds[7] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A4_PLUS3);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
tssi_bounds[8] = rt2x00_get_field16(eeprom,
EEPROM_TSSI_BOUND_A5_PLUS4);
@@ -2899,7 +2920,7 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
u8 comp_type;
int comp_value = 0;
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
/*
* HT40 compensation not required.
@@ -2974,12 +2995,12 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
* .11b data rate need add additional 4dbm
* when calculating eirp txpower.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
&eeprom);
criterion = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER,
&eeprom);
if (band == IEEE80211_BAND_2GHZ)
@@ -3080,7 +3101,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, offset, ®);
/* read the next four txpower values */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
&eeprom);
is_rate_b = i ? 0 : 1;
@@ -3129,7 +3150,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower);
/* read the next four txpower values */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
&eeprom);
is_rate_b = 0;
@@ -3528,7 +3549,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
+ &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x0000002c);
@@ -3989,7 +4011,7 @@ static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
u8 value;
rt2800_bbp_read(rt2x00dev, 138, &value);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
value |= 0x20;
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
@@ -4402,7 +4424,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
rt2800_disable_unused_dac_adc(rt2x00dev);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
div_mode = rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_ANT_DIVERSITY);
ant = (div_mode == 3) ? 1 : 0;
@@ -4488,7 +4510,7 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
rt2800_bbp4_mac_if_ctrl(rt2x00dev);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
ant = (div_mode == 3) ? 1 : 0;
rt2800_bbp_read(rt2x00dev, 152, &value);
@@ -4557,7 +4579,7 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
}
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
if (eeprom != 0xffff && eeprom != 0x0000) {
reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
@@ -4728,7 +4750,7 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3090)) {
/* Turn off unused DAC1 and ADC1 to reduce power consumption */
rt2800_bbp_read(rt2x00dev, 138, &bbp);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
@@ -4778,7 +4800,7 @@ static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev)
/* Turn off unused DAC1 and ADC1 to reduce power consumption */
rt2800_bbp_read(rt2x00dev, 138, ®);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
rt2x00_set_field8(®, BBP138_RX_ADC1, 0);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
@@ -4884,7 +4906,8 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1,
+ &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3);
else
@@ -5456,15 +5479,15 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize LED control
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
word & 0xff, (word >> 8) & 0xff);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
word & 0xff, (word >> 8) & 0xff);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
word & 0xff, (word >> 8) & 0xff);
@@ -5578,18 +5601,18 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Start validation of the data that has been read.
*/
- mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+ mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
if (!is_valid_ether_addr(mac)) {
eth_random_addr(mac);
rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2872)) {
@@ -5598,10 +5621,10 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
*/
if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
@@ -5618,24 +5641,24 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
if ((word & 0x00ff) == 0x00ff) {
rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word);
}
if ((word & 0xff00) == 0xff00) {
rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
LED_MODE_TXRX_ACTIVITY);
rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word);
}
@@ -5644,17 +5667,17 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
* lna0 as correct value. Note that EEPROM_LNA
* is never validated.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
if ((word & 0x00ff) != 0x00ff) {
drv_data->txmixer_gain_24g =
rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
@@ -5662,16 +5685,16 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
drv_data->txmixer_gain_24g = 0;
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
default_lna_gain);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
if ((word & 0x00ff) != 0x00ff) {
drv_data->txmixer_gain_5g =
rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
@@ -5679,21 +5702,21 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
drv_data->txmixer_gain_5g = 0;
}
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
default_lna_gain);
- rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+ rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
return 0;
}
@@ -5707,7 +5730,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Read EEPROM word for configuration.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
/*
* Identify RF chipset by EEPROM value
@@ -5717,7 +5740,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
- rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
else
rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
@@ -5757,7 +5780,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00dev->default_ant.rx_chain_num =
rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3090) ||
@@ -5810,7 +5833,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Read frequency offset and RF programming sequence.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
/*
@@ -5827,7 +5850,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Check if support EIRP tx power limit feature.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
EIRP_MAX_TX_POWER_LIMIT)
@@ -6148,7 +6171,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
- rt2x00_eeprom_addr(rt2x00dev,
+ rt2800_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
/*
@@ -6164,7 +6187,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->max_report_rates = 7;
rt2x00dev->hw->max_rate_tries = 1;
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
/*
* Initialize hw_mode information.
@@ -6264,8 +6287,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->channels_info = info;
- default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
- default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+ default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+ default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
for (i = 0; i < 14; i++) {
info[i].default_power1 = default_power1[i];
@@ -6273,8 +6296,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
}
if (spec->num_channels > 14) {
- default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
- default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+ default_power1 = rt2800_eeprom_addr(rt2x00dev,
+ EEPROM_TXPOWER_A1);
+ default_power2 = rt2800_eeprom_addr(rt2x00dev,
+ EEPROM_TXPOWER_A2);
for (i = 14; i < spec->num_channels; i++) {
info[i].default_power1 = default_power1[i - 14];
--
1.7.10
^ permalink raw reply related
* [PATCH v2 3/5] rt2x00: rt2800lib: introduce rt2800_eeprom_read_from_array helper
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1373275556-6482-1-git-send-email-juhosg@openwrt.org>
Add a new helper function and use that for reading
single elements of various arrays in the EEPROM.
The patch does not change the current behaviour,
but it allows to use sequential values for the
rt2800_eeprom_word enums. The conversion will be
implemented in a subsequent change.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800lib.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 522f0b1..b59772a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -239,6 +239,14 @@ static void rt2800_eeprom_write(struct rt2x00_dev *rt2x00dev,
rt2x00_eeprom_write(rt2x00dev, word, data);
}
+static void rt2800_eeprom_read_from_array(struct rt2x00_dev *rt2x00dev,
+ const enum rt2800_eeprom_word array,
+ unsigned int offset,
+ u16 *data)
+{
+ rt2x00_eeprom_read(rt2x00dev, array + offset, data);
+}
+
static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
@@ -2995,8 +3003,8 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
* .11b data rate need add additional 4dbm
* when calculating eirp txpower.
*/
- rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1,
- &eeprom);
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ 1, &eeprom);
criterion = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
@@ -3101,8 +3109,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2800_register_read(rt2x00dev, offset, ®);
/* read the next four txpower values */
- rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
- &eeprom);
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ i, &eeprom);
is_rate_b = i ? 0 : 1;
/*
@@ -3150,8 +3158,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower);
/* read the next four txpower values */
- rt2800_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
- &eeprom);
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_TXPOWER_BYRATE,
+ i + 1, &eeprom);
is_rate_b = 0;
/*
@@ -4579,7 +4587,8 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
}
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
- rt2800_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+ rt2800_eeprom_read_from_array(rt2x00dev, EEPROM_BBP_START, i,
+ &eeprom);
if (eeprom != 0xffff && eeprom != 0x0000) {
reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
--
1.7.10
^ permalink raw reply related
* [PATCH v2 1/5] rt2x00: rt2800lib: introduce rt2800_eeprom_word enum
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1373275556-6482-1-git-send-email-juhosg@openwrt.org>
The patch converts the EEPROM_* word address defines
into new enum values. The new enum type will be used
by new functions which will be introduced in subsequent
changes.
The patch contains no functional changes.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1: ---
---
drivers/net/wireless/rt2x00/rt2800.h | 79 +++++++++++++++++-----------------
1 file changed, 39 insertions(+), 40 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index d78c495..0647039 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2206,28 +2206,59 @@ struct mac_iveiv_entry {
* The wordsize of the EEPROM is 16 bits.
*/
-/*
- * Chip ID
- */
-#define EEPROM_CHIP_ID 0x0000
+enum rt2800_eeprom_word {
+ EEPROM_CHIP_ID = 0x0000,
+ EEPROM_VERSION = 0x0001,
+ EEPROM_MAC_ADDR_0 = 0x0002,
+ EEPROM_MAC_ADDR_1 = 0x0003,
+ EEPROM_MAC_ADDR_2 = 0x0004,
+ EEPROM_NIC_CONF0 = 0x001a,
+ EEPROM_NIC_CONF1 = 0x001b,
+ EEPROM_FREQ = 0x001d,
+ EEPROM_LED_AG_CONF = 0x001e,
+ EEPROM_LED_ACT_CONF = 0x001f,
+ EEPROM_LED_POLARITY = 0x0020,
+ EEPROM_NIC_CONF2 = 0x0021,
+ EEPROM_LNA = 0x0022,
+ EEPROM_RSSI_BG = 0x0023,
+ EEPROM_RSSI_BG2 = 0x0024,
+ EEPROM_TXMIXER_GAIN_BG = 0x0024, /* overlaps with RSSI_BG2 */
+ EEPROM_RSSI_A = 0x0025,
+ EEPROM_RSSI_A2 = 0x0026,
+ EEPROM_TXMIXER_GAIN_A = 0x0026, /* overlaps with RSSI_A2 */
+ EEPROM_EIRP_MAX_TX_POWER = 0x0027,
+ EEPROM_TXPOWER_DELTA = 0x0028,
+ EEPROM_TXPOWER_BG1 = 0x0029,
+ EEPROM_TXPOWER_BG2 = 0x0030,
+ EEPROM_TSSI_BOUND_BG1 = 0x0037,
+ EEPROM_TSSI_BOUND_BG2 = 0x0038,
+ EEPROM_TSSI_BOUND_BG3 = 0x0039,
+ EEPROM_TSSI_BOUND_BG4 = 0x003a,
+ EEPROM_TSSI_BOUND_BG5 = 0x003b,
+ EEPROM_TXPOWER_A1 = 0x003c,
+ EEPROM_TXPOWER_A2 = 0x0053,
+ EEPROM_TSSI_BOUND_A1 = 0x006a,
+ EEPROM_TSSI_BOUND_A2 = 0x006b,
+ EEPROM_TSSI_BOUND_A3 = 0x006c,
+ EEPROM_TSSI_BOUND_A4 = 0x006d,
+ EEPROM_TSSI_BOUND_A5 = 0x006e,
+ EEPROM_TXPOWER_BYRATE = 0x006f,
+ EEPROM_BBP_START = 0x0078,
+};
/*
* EEPROM Version
*/
-#define EEPROM_VERSION 0x0001
#define EEPROM_VERSION_FAE FIELD16(0x00ff)
#define EEPROM_VERSION_VERSION FIELD16(0xff00)
/*
* HW MAC address.
*/
-#define EEPROM_MAC_ADDR_0 0x0002
#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff)
#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00)
-#define EEPROM_MAC_ADDR_1 0x0003
#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff)
#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00)
-#define EEPROM_MAC_ADDR_2 0x0004
#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff)
#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
@@ -2237,7 +2268,6 @@ struct mac_iveiv_entry {
* TXPATH: 1: 1T, 2: 2T, 3: 3T
* RF_TYPE: RFIC type
*/
-#define EEPROM_NIC_CONF0 0x001a
#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
@@ -2261,7 +2291,6 @@ struct mac_iveiv_entry {
* BT_COEXIST: 0: disable, 1: enable
* DAC_TEST: 0: disable, 1: enable
*/
-#define EEPROM_NIC_CONF1 0x001b
#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
@@ -2281,7 +2310,6 @@ struct mac_iveiv_entry {
/*
* EEPROM frequency
*/
-#define EEPROM_FREQ 0x001d
#define EEPROM_FREQ_OFFSET FIELD16(0x00ff)
#define EEPROM_FREQ_LED_MODE FIELD16(0x7f00)
#define EEPROM_FREQ_LED_POLARITY FIELD16(0x1000)
@@ -2298,9 +2326,6 @@ struct mac_iveiv_entry {
* POLARITY_GPIO_4: Polarity GPIO4 setting.
* LED_MODE: Led mode.
*/
-#define EEPROM_LED_AG_CONF 0x001e
-#define EEPROM_LED_ACT_CONF 0x001f
-#define EEPROM_LED_POLARITY 0x0020
#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
@@ -2317,7 +2342,6 @@ struct mac_iveiv_entry {
* TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
* CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
*/
-#define EEPROM_NIC_CONF2 0x0021
#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
@@ -2325,54 +2349,46 @@ struct mac_iveiv_entry {
/*
* EEPROM LNA
*/
-#define EEPROM_LNA 0x0022
#define EEPROM_LNA_BG FIELD16(0x00ff)
#define EEPROM_LNA_A0 FIELD16(0xff00)
/*
* EEPROM RSSI BG offset
*/
-#define EEPROM_RSSI_BG 0x0023
#define EEPROM_RSSI_BG_OFFSET0 FIELD16(0x00ff)
#define EEPROM_RSSI_BG_OFFSET1 FIELD16(0xff00)
/*
* EEPROM RSSI BG2 offset
*/
-#define EEPROM_RSSI_BG2 0x0024
#define EEPROM_RSSI_BG2_OFFSET2 FIELD16(0x00ff)
#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
/*
* EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
*/
-#define EEPROM_TXMIXER_GAIN_BG 0x0024
#define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007)
/*
* EEPROM RSSI A offset
*/
-#define EEPROM_RSSI_A 0x0025
#define EEPROM_RSSI_A_OFFSET0 FIELD16(0x00ff)
#define EEPROM_RSSI_A_OFFSET1 FIELD16(0xff00)
/*
* EEPROM RSSI A2 offset
*/
-#define EEPROM_RSSI_A2 0x0026
#define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff)
#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
/*
* EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
*/
-#define EEPROM_TXMIXER_GAIN_A 0x0026
#define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007)
/*
* EEPROM EIRP Maximum TX power values(unit: dbm)
*/
-#define EEPROM_EIRP_MAX_TX_POWER 0x0027
#define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff)
#define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00)
@@ -2383,7 +2399,6 @@ struct mac_iveiv_entry {
* TYPE: 1: Plus the delta value, 0: minus the delta value
* ENABLE: enable tx power compensation for 40BW
*/
-#define EEPROM_TXPOWER_DELTA 0x0028
#define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f)
#define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040)
#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080)
@@ -2394,8 +2409,6 @@ struct mac_iveiv_entry {
/*
* EEPROM TXPOWER 802.11BG
*/
-#define EEPROM_TXPOWER_BG1 0x0029
-#define EEPROM_TXPOWER_BG2 0x0030
#define EEPROM_TXPOWER_BG_SIZE 7
#define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff)
#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
@@ -2407,7 +2420,6 @@ struct mac_iveiv_entry {
* MINUS3: If the actual TSSI is below this boundary, tx power needs to be
* reduced by (agc_step * -3)
*/
-#define EEPROM_TSSI_BOUND_BG1 0x0037
#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00)
@@ -2418,7 +2430,6 @@ struct mac_iveiv_entry {
* MINUS1: If the actual TSSI is below this boundary, tx power needs to be
* reduced by (agc_step * -1)
*/
-#define EEPROM_TSSI_BOUND_BG2 0x0038
#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00)
@@ -2428,7 +2439,6 @@ struct mac_iveiv_entry {
* PLUS1: If the actual TSSI is above this boundary, tx power needs to be
* increased by (agc_step * 1)
*/
-#define EEPROM_TSSI_BOUND_BG3 0x0039
#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00)
@@ -2439,7 +2449,6 @@ struct mac_iveiv_entry {
* PLUS3: If the actual TSSI is above this boundary, tx power needs to be
* increased by (agc_step * 3)
*/
-#define EEPROM_TSSI_BOUND_BG4 0x003a
#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00)
@@ -2449,15 +2458,12 @@ struct mac_iveiv_entry {
* increased by (agc_step * 4)
* AGC_STEP: Temperature compensation step.
*/
-#define EEPROM_TSSI_BOUND_BG5 0x003b
#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00)
/*
* EEPROM TXPOWER 802.11A
*/
-#define EEPROM_TXPOWER_A1 0x003c
-#define EEPROM_TXPOWER_A2 0x0053
#define EEPROM_TXPOWER_A_SIZE 6
#define EEPROM_TXPOWER_A_1 FIELD16(0x00ff)
#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
@@ -2469,7 +2475,6 @@ struct mac_iveiv_entry {
* MINUS3: If the actual TSSI is below this boundary, tx power needs to be
* reduced by (agc_step * -3)
*/
-#define EEPROM_TSSI_BOUND_A1 0x006a
#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00)
@@ -2480,7 +2485,6 @@ struct mac_iveiv_entry {
* MINUS1: If the actual TSSI is below this boundary, tx power needs to be
* reduced by (agc_step * -1)
*/
-#define EEPROM_TSSI_BOUND_A2 0x006b
#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00)
@@ -2490,7 +2494,6 @@ struct mac_iveiv_entry {
* PLUS1: If the actual TSSI is above this boundary, tx power needs to be
* increased by (agc_step * 1)
*/
-#define EEPROM_TSSI_BOUND_A3 0x006c
#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00)
@@ -2501,7 +2504,6 @@ struct mac_iveiv_entry {
* PLUS3: If the actual TSSI is above this boundary, tx power needs to be
* increased by (agc_step * 3)
*/
-#define EEPROM_TSSI_BOUND_A4 0x006d
#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00)
@@ -2511,14 +2513,12 @@ struct mac_iveiv_entry {
* increased by (agc_step * 4)
* AGC_STEP: Temperature compensation step.
*/
-#define EEPROM_TSSI_BOUND_A5 0x006e
#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff)
#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00)
/*
* EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
*/
-#define EEPROM_TXPOWER_BYRATE 0x006f
#define EEPROM_TXPOWER_BYRATE_SIZE 9
#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f)
@@ -2529,7 +2529,6 @@ struct mac_iveiv_entry {
/*
* EEPROM BBP.
*/
-#define EEPROM_BBP_START 0x0078
#define EEPROM_BBP_SIZE 16
#define EEPROM_BBP_VALUE FIELD16(0x00ff)
#define EEPROM_BBP_REG_ID FIELD16(0xff00)
--
1.7.10
^ permalink raw reply related
* [PATCH v2 0/5] rt2800lib: add support for extended EEPROM of three-cain devices
From: Gabor Juhos @ 2013-07-08 9:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
Gabor Juhos (5):
rt2x00: rt2800lib: introduce rt2800_eeprom_word enum
rt2x00: rt2800lib: introduce local EEPROM access functions
rt2x00: rt2800lib: introduce rt2800_eeprom_read_from_array helper
rt2x00: rt2800lib: introduce rt2800_eeprom_word_index helper
rt2x00: rt2800lib: add EEPROM map for the RT3593 chipset
drivers/net/wireless/rt2x00/rt2800.h | 87 +++++----
drivers/net/wireless/rt2x00/rt2800lib.c | 305 +++++++++++++++++++++++--------
2 files changed, 279 insertions(+), 113 deletions(-)
--
1.7.10
^ permalink raw reply
* Re: [PATCH] mac80211: add per-chain signal information to radiotap
From: Johannes Berg @ 2013-07-08 8:56 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <1372851242-25474-1-git-send-email-johannes@sipsolutions.net>
On Wed, 2013-07-03 at 13:34 +0200, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> When per-chain signal information is available, don't add
> the antenna field once but instead add a radiotap namespace
> for each chain containing the chain/antenna number and the
> signal strength on that chain.
Applied.
johannes
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox