mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
mac80211: dont use interface indices in drivers
This patch gets rid of the if_id stuff where possible in favour of a new per-virtual-interface structure "struct ieee80211_vif". This structure is located at the end of the per-interface structure and contains a variable length driver-use data area. This has two advantages: * removes the need to look up interfaces by if_id, this is better for working with network namespaces and performance * allows drivers to store and retrieve per-interface data without having to allocate own lists/hash tables Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
parent
f653211197
commit
32bfd35d4b
29 changed files with 205 additions and 174 deletions
|
|
@ -243,7 +243,7 @@ static int ieee80211_open(struct net_device *dev)
|
|||
sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
|
||||
/* fall through */
|
||||
default:
|
||||
conf.if_id = dev->ifindex;
|
||||
conf.vif = &sdata->vif;
|
||||
conf.type = sdata->type;
|
||||
conf.mac_addr = dev->dev_addr;
|
||||
res = local->ops->add_interface(local_to_hw(local), &conf);
|
||||
|
|
@ -378,7 +378,7 @@ static int ieee80211_stop(struct net_device *dev)
|
|||
sdata->u.sta.extra_ie_len = 0;
|
||||
/* fall through */
|
||||
default:
|
||||
conf.if_id = dev->ifindex;
|
||||
conf.vif = &sdata->vif;
|
||||
conf.type = sdata->type;
|
||||
conf.mac_addr = dev->dev_addr;
|
||||
/* disable all keys for as long as this netdev is down */
|
||||
|
|
@ -515,7 +515,7 @@ static int __ieee80211_if_config(struct net_device *dev,
|
|||
conf.beacon_control = control;
|
||||
}
|
||||
return local->ops->config_interface(local_to_hw(local),
|
||||
dev->ifindex, &conf);
|
||||
&sdata->vif, &conf);
|
||||
}
|
||||
|
||||
int ieee80211_if_config(struct net_device *dev)
|
||||
|
|
@ -527,11 +527,13 @@ int ieee80211_if_config_beacon(struct net_device *dev)
|
|||
{
|
||||
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
struct ieee80211_tx_control control;
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
|
||||
return 0;
|
||||
skb = ieee80211_beacon_get(local_to_hw(local), dev->ifindex, &control);
|
||||
skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif,
|
||||
&control);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
return __ieee80211_if_config(dev, skb, &control);
|
||||
|
|
@ -736,7 +738,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
|
|||
struct ieee80211_tx_packet_data *pkt_data;
|
||||
|
||||
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
|
||||
pkt_data->ifindex = control->ifindex;
|
||||
pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex;
|
||||
pkt_data->flags = 0;
|
||||
if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS)
|
||||
pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
|
||||
|
|
|
|||
|
|
@ -387,8 +387,16 @@ struct ieee80211_sub_if_data {
|
|||
struct dentry *default_key;
|
||||
} debugfs;
|
||||
#endif
|
||||
/* must be last, dynamically sized area in this! */
|
||||
struct ieee80211_vif vif;
|
||||
};
|
||||
|
||||
static inline
|
||||
struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
|
||||
{
|
||||
return container_of(p, struct ieee80211_sub_if_data, vif);
|
||||
}
|
||||
|
||||
#define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev)
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
|
|||
int ret;
|
||||
|
||||
ASSERT_RTNL();
|
||||
ndev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
|
||||
ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size,
|
||||
name, ieee80211_if_setup);
|
||||
if (!ndev)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -177,9 +177,16 @@ struct sta_info * sta_info_add(struct ieee80211_local *local,
|
|||
list_add(&sta->list, &local->sta_list);
|
||||
local->num_sta++;
|
||||
sta_info_hash_add(local, sta);
|
||||
if (local->ops->sta_notify)
|
||||
local->ops->sta_notify(local_to_hw(local), dev->ifindex,
|
||||
STA_NOTIFY_ADD, addr);
|
||||
if (local->ops->sta_notify) {
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
if (sdata->type == IEEE80211_IF_TYPE_VLAN)
|
||||
sdata = sdata->u.vlan.ap;
|
||||
|
||||
local->ops->sta_notify(local_to_hw(local), &sdata->vif,
|
||||
STA_NOTIFY_ADD, addr);
|
||||
}
|
||||
write_unlock_bh(&local->sta_lock);
|
||||
|
||||
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
||||
|
|
@ -247,9 +254,17 @@ void sta_info_free(struct sta_info *sta)
|
|||
ieee80211_key_free(sta->key);
|
||||
sta->key = NULL;
|
||||
|
||||
if (local->ops->sta_notify)
|
||||
local->ops->sta_notify(local_to_hw(local), sta->dev->ifindex,
|
||||
STA_NOTIFY_REMOVE, sta->addr);
|
||||
if (local->ops->sta_notify) {
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
|
||||
|
||||
if (sdata->type == IEEE80211_IF_TYPE_VLAN)
|
||||
sdata = sdata->u.vlan.ap;
|
||||
|
||||
local->ops->sta_notify(local_to_hw(local), &sdata->vif,
|
||||
STA_NOTIFY_REMOVE, sta->addr);
|
||||
}
|
||||
|
||||
rate_control_remove_sta_debugfs(sta);
|
||||
ieee80211_sta_debugfs_remove(sta);
|
||||
|
|
|
|||
|
|
@ -999,9 +999,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
|
|||
return TXRX_CONTINUE;
|
||||
}
|
||||
|
||||
/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
|
||||
* finished with it.
|
||||
*
|
||||
/*
|
||||
* NB: @tx is uninitialised when passed in here
|
||||
*/
|
||||
static int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
|
||||
|
|
@ -1022,6 +1020,7 @@ static int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
|
|||
return -ENODEV;
|
||||
/* initialises tx with control */
|
||||
__ieee80211_tx_prepare(tx, skb, dev, control);
|
||||
dev_put(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1252,7 +1251,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
|
|||
}
|
||||
}
|
||||
|
||||
control.ifindex = odev->ifindex;
|
||||
control.vif = &osdata->vif;
|
||||
control.type = osdata->type;
|
||||
if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS)
|
||||
control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS;
|
||||
|
|
@ -1691,7 +1690,8 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
|
|||
read_unlock_bh(&local->sta_lock);
|
||||
}
|
||||
|
||||
struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
|
||||
struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_tx_control *control)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
|
@ -1703,19 +1703,16 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
|
|||
u8 *b_head, *b_tail;
|
||||
int bh_len, bt_len;
|
||||
|
||||
bdev = dev_get_by_index(&init_net, if_id);
|
||||
if (bdev) {
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
|
||||
ap = &sdata->u.ap;
|
||||
dev_put(bdev);
|
||||
}
|
||||
sdata = vif_to_sdata(vif);
|
||||
bdev = sdata->dev;
|
||||
ap = &sdata->u.ap;
|
||||
|
||||
if (!ap || sdata->type != IEEE80211_IF_TYPE_AP ||
|
||||
!ap->beacon_head) {
|
||||
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
||||
if (net_ratelimit())
|
||||
printk(KERN_DEBUG "no beacon data avail for idx=%d "
|
||||
"(%s)\n", if_id, bdev ? bdev->name : "N/A");
|
||||
printk(KERN_DEBUG "no beacon data avail for %s\n",
|
||||
bdev->name);
|
||||
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1771,7 +1768,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_beacon_get);
|
||||
|
||||
void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
|
||||
void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
const void *frame, size_t frame_len,
|
||||
const struct ieee80211_tx_control *frame_txctl,
|
||||
struct ieee80211_rts *rts)
|
||||
|
|
@ -1781,13 +1778,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
|
|||
|
||||
fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
|
||||
rts->frame_control = cpu_to_le16(fctl);
|
||||
rts->duration = ieee80211_rts_duration(hw, if_id, frame_len, frame_txctl);
|
||||
rts->duration = ieee80211_rts_duration(hw, vif, frame_len,
|
||||
frame_txctl);
|
||||
memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
|
||||
memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_rts_get);
|
||||
|
||||
void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
|
||||
void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
const void *frame, size_t frame_len,
|
||||
const struct ieee80211_tx_control *frame_txctl,
|
||||
struct ieee80211_cts *cts)
|
||||
|
|
@ -1797,13 +1795,15 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
|
|||
|
||||
fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
|
||||
cts->frame_control = cpu_to_le16(fctl);
|
||||
cts->duration = ieee80211_ctstoself_duration(hw, if_id, frame_len, frame_txctl);
|
||||
cts->duration = ieee80211_ctstoself_duration(hw, vif,
|
||||
frame_len, frame_txctl);
|
||||
memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_ctstoself_get);
|
||||
|
||||
struct sk_buff *
|
||||
ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
|
||||
ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_tx_control *control)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
|
@ -1816,12 +1816,9 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
|
|||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_if_ap *bss = NULL;
|
||||
|
||||
bdev = dev_get_by_index(&init_net, if_id);
|
||||
if (bdev) {
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
|
||||
bss = &sdata->u.ap;
|
||||
dev_put(bdev);
|
||||
}
|
||||
sdata = vif_to_sdata(vif);
|
||||
bdev = sdata->dev;
|
||||
|
||||
if (!bss || sdata->type != IEEE80211_IF_TYPE_AP || !bss->beacon_head)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1857,7 +1854,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
|
|||
if (res == TXRX_DROP || res == TXRX_QUEUED)
|
||||
break;
|
||||
}
|
||||
dev_put(tx.dev);
|
||||
skb = tx.skb; /* handlers are allowed to change skb */
|
||||
|
||||
if (res == TXRX_DROP) {
|
||||
|
|
|
|||
|
|
@ -302,44 +302,34 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
|
|||
}
|
||||
|
||||
/* Exported duration function for driver use */
|
||||
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
|
||||
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
size_t frame_len, int rate)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct net_device *bdev = dev_get_by_index(&init_net, if_id);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
u16 dur;
|
||||
int erp;
|
||||
|
||||
if (unlikely(!bdev))
|
||||
return 0;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
|
||||
erp = ieee80211_is_erp_rate(hw->conf.phymode, rate);
|
||||
dur = ieee80211_frame_duration(local, frame_len, rate,
|
||||
erp, sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
|
||||
|
||||
dev_put(bdev);
|
||||
return cpu_to_le16(dur);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_generic_frame_duration);
|
||||
|
||||
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
|
||||
size_t frame_len,
|
||||
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif, size_t frame_len,
|
||||
const struct ieee80211_tx_control *frame_txctl)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_rate *rate;
|
||||
struct net_device *bdev = dev_get_by_index(&init_net, if_id);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
int short_preamble;
|
||||
int erp;
|
||||
u16 dur;
|
||||
|
||||
if (unlikely(!bdev))
|
||||
return 0;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
|
||||
short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE;
|
||||
|
||||
rate = frame_txctl->rts_rate;
|
||||
|
|
@ -355,27 +345,22 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
|
|||
dur += ieee80211_frame_duration(local, 10, rate->rate,
|
||||
erp, short_preamble);
|
||||
|
||||
dev_put(bdev);
|
||||
return cpu_to_le16(dur);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_rts_duration);
|
||||
|
||||
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
|
||||
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
size_t frame_len,
|
||||
const struct ieee80211_tx_control *frame_txctl)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_rate *rate;
|
||||
struct net_device *bdev = dev_get_by_index(&init_net, if_id);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
int short_preamble;
|
||||
int erp;
|
||||
u16 dur;
|
||||
|
||||
if (unlikely(!bdev))
|
||||
return 0;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
|
||||
short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE;
|
||||
|
||||
rate = frame_txctl->rts_rate;
|
||||
|
|
@ -390,7 +375,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
|
|||
erp, short_preamble);
|
||||
}
|
||||
|
||||
dev_put(bdev);
|
||||
return cpu_to_le16(dur);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_ctstoself_duration);
|
||||
|
|
@ -475,10 +459,11 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_wake_queues);
|
||||
|
||||
void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
|
||||
void (*iterator)(void *data, u8 *mac,
|
||||
int if_id),
|
||||
void *data)
|
||||
void ieee80211_iterate_active_interfaces(
|
||||
struct ieee80211_hw *hw,
|
||||
void (*iterator)(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif),
|
||||
void *data)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
|
@ -501,7 +486,7 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
|
|||
continue;
|
||||
if (netif_running(sdata->dev))
|
||||
iterator(data, sdata->dev->dev_addr,
|
||||
sdata->dev->ifindex);
|
||||
&sdata->vif);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
|
|
|||
Loading…
Reference in a new issue