mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add latest and patched mac80211 ans hostapd packages
This commit is contained in:
parent
e5395f65eb
commit
bdff38dfc4
321 changed files with 36273 additions and 0 deletions
1980
root/package/kernel/mac80211/Makefile
Normal file
1980
root/package/kernel/mac80211/Makefile
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,836 @@
|
|||
#!/bin/sh
|
||||
. /lib/netifd/netifd-wireless.sh
|
||||
. /lib/netifd/hostapd.sh
|
||||
|
||||
init_wireless_driver "$@"
|
||||
|
||||
MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links
|
||||
mesh_max_retries mesh_ttl mesh_element_ttl mesh_hwmp_max_preq_retries
|
||||
mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout
|
||||
mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode
|
||||
mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor
|
||||
mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval
|
||||
mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout"
|
||||
MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding"
|
||||
MP_CONFIG_STRING="mesh_power_mode"
|
||||
|
||||
drv_mac80211_init_device_config() {
|
||||
hostapd_common_add_device_config
|
||||
|
||||
config_add_string path phy 'macaddr:macaddr'
|
||||
config_add_string hwmode
|
||||
config_add_int beacon_int chanbw frag rts
|
||||
config_add_int rxantenna txantenna antenna_gain txpower distance
|
||||
config_add_boolean noscan ht_coex
|
||||
config_add_array ht_capab
|
||||
config_add_array channels
|
||||
config_add_boolean \
|
||||
rxldpc \
|
||||
short_gi_80 \
|
||||
short_gi_160 \
|
||||
tx_stbc_2by1 \
|
||||
su_beamformer \
|
||||
su_beamformee \
|
||||
mu_beamformer \
|
||||
mu_beamformee \
|
||||
vht_txop_ps \
|
||||
htc_vht \
|
||||
rx_antenna_pattern \
|
||||
tx_antenna_pattern
|
||||
config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc
|
||||
config_add_boolean \
|
||||
ldpc \
|
||||
greenfield \
|
||||
short_gi_20 \
|
||||
short_gi_40 \
|
||||
max_amsdu \
|
||||
dsss_cck_40
|
||||
}
|
||||
|
||||
drv_mac80211_init_iface_config() {
|
||||
hostapd_common_add_bss_config
|
||||
|
||||
config_add_string 'macaddr:macaddr' ifname
|
||||
|
||||
config_add_boolean wds powersave
|
||||
config_add_int maxassoc
|
||||
config_add_int max_listen_int
|
||||
config_add_int dtim_period
|
||||
config_add_int start_disabled
|
||||
|
||||
# mesh
|
||||
config_add_string mesh_id
|
||||
config_add_int $MP_CONFIG_INT
|
||||
config_add_boolean $MP_CONFIG_BOOL
|
||||
config_add_string $MP_CONFIG_STRING
|
||||
}
|
||||
|
||||
mac80211_add_capabilities() {
|
||||
local __var="$1"; shift
|
||||
local __mask="$1"; shift
|
||||
local __out= oifs
|
||||
|
||||
oifs="$IFS"
|
||||
IFS=:
|
||||
for capab in "$@"; do
|
||||
set -- $capab
|
||||
|
||||
[ "$(($4))" -gt 0 ] || continue
|
||||
[ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue
|
||||
__out="$__out[$1]"
|
||||
done
|
||||
IFS="$oifs"
|
||||
|
||||
export -n -- "$__var=$__out"
|
||||
}
|
||||
|
||||
mac80211_hostapd_setup_base() {
|
||||
local phy="$1"
|
||||
|
||||
json_select config
|
||||
|
||||
[ "$auto_channel" -gt 0 ] && channel=acs_survey
|
||||
[ "$auto_channel" -gt 0 ] && json_get_values channel_list channels
|
||||
|
||||
json_get_vars noscan ht_coex
|
||||
json_get_values ht_capab_list ht_capab
|
||||
|
||||
ieee80211n=1
|
||||
ht_capab=
|
||||
case "$htmode" in
|
||||
VHT20|HT20) ;;
|
||||
HT40*|VHT40|VHT80|VHT160)
|
||||
case "$hwmode" in
|
||||
a)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) ht_capab="[HT40+]";;
|
||||
0) ht_capab="[HT40-]";;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$htmode" in
|
||||
HT40+) ht_capab="[HT40+]";;
|
||||
HT40-) ht_capab="[HT40-]";;
|
||||
*)
|
||||
if [ "$channel" -lt 7 ]; then
|
||||
ht_capab="[HT40+]"
|
||||
else
|
||||
ht_capab="[HT40-]"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
[ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]"
|
||||
;;
|
||||
*) ieee80211n= ;;
|
||||
esac
|
||||
|
||||
[ -n "$ieee80211n" ] && {
|
||||
append base_cfg "ieee80211n=1" "$N"
|
||||
|
||||
set_default ht_coex 0
|
||||
append base_cfg "ht_coex=$ht_coex" "$N"
|
||||
|
||||
json_get_vars \
|
||||
ldpc:1 \
|
||||
greenfield:0 \
|
||||
short_gi_20:1 \
|
||||
short_gi_40:0 \
|
||||
tx_stbc:1 \
|
||||
rx_stbc:3 \
|
||||
max_amsdu:1 \
|
||||
dsss_cck_40:1
|
||||
|
||||
ht_cap_mask=0
|
||||
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
|
||||
ht_cap_mask="$(($ht_cap_mask | $cap))"
|
||||
done
|
||||
|
||||
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
|
||||
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
|
||||
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
|
||||
|
||||
mac80211_add_capabilities ht_capab_flags $ht_cap_mask \
|
||||
LDPC:0x1::$ldpc \
|
||||
GF:0x10::$greenfield \
|
||||
SHORT-GI-20:0x20::$short_gi_20 \
|
||||
SHORT-GI-40:0x40::$short_gi_40 \
|
||||
TX-STBC:0x80::$tx_stbc \
|
||||
RX-STBC1:0x300:0x100:1 \
|
||||
RX-STBC12:0x300:0x200:1 \
|
||||
RX-STBC123:0x300:0x300:1 \
|
||||
MAX-AMSDU-7935:0x800::$max_amsdu \
|
||||
DSSS_CCK-40:0x1000::$dsss_cck_40
|
||||
|
||||
ht_capab="$ht_capab$ht_capab_flags"
|
||||
[ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
|
||||
}
|
||||
|
||||
# 802.11ac
|
||||
enable_ac=0
|
||||
idx="$channel"
|
||||
case "$htmode" in
|
||||
VHT20) enable_ac=1;;
|
||||
VHT40)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) idx=$(($channel + 2));;
|
||||
0) idx=$(($channel - 2));;
|
||||
esac
|
||||
enable_ac=1
|
||||
append base_cfg "vht_oper_chwidth=0" "$N"
|
||||
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
|
||||
;;
|
||||
VHT80)
|
||||
case "$(( ($channel / 4) % 4 ))" in
|
||||
1) idx=$(($channel + 6));;
|
||||
2) idx=$(($channel + 2));;
|
||||
3) idx=$(($channel - 2));;
|
||||
0) idx=$(($channel - 6));;
|
||||
esac
|
||||
enable_ac=1
|
||||
append base_cfg "vht_oper_chwidth=1" "$N"
|
||||
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
|
||||
;;
|
||||
VHT160)
|
||||
case "$channel" in
|
||||
36|40|44|48|52|56|60|64) idx=50;;
|
||||
100|104|108|112|116|120|124|128) idx=114;;
|
||||
esac
|
||||
enable_ac=1
|
||||
append base_cfg "vht_oper_chwidth=2" "$N"
|
||||
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$enable_ac" != "0" ]; then
|
||||
json_get_vars \
|
||||
rxldpc:1 \
|
||||
short_gi_80:1 \
|
||||
short_gi_160:1 \
|
||||
tx_stbc_2by1:1 \
|
||||
su_beamformer:1 \
|
||||
su_beamformee:1 \
|
||||
mu_beamformer:1 \
|
||||
mu_beamformee:1 \
|
||||
vht_txop_ps:1 \
|
||||
htc_vht:1 \
|
||||
rx_antenna_pattern:1 \
|
||||
tx_antenna_pattern:1 \
|
||||
vht_max_a_mpdu_len_exp:7 \
|
||||
vht_max_mpdu:11454 \
|
||||
rx_stbc:4 \
|
||||
vht_link_adapt:3 \
|
||||
vht160:2
|
||||
|
||||
append base_cfg "ieee80211ac=1" "$N"
|
||||
vht_cap=0
|
||||
for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do
|
||||
vht_cap="$(($vht_cap | $cap))"
|
||||
done
|
||||
|
||||
cap_rx_stbc=$((($vht_cap >> 8) & 7))
|
||||
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
|
||||
vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
|
||||
|
||||
mac80211_add_capabilities vht_capab $vht_cap \
|
||||
RXLDPC:0x10::$rxldpc \
|
||||
SHORT-GI-80:0x20::$short_gi_80 \
|
||||
SHORT-GI-160:0x40::$short_gi_160 \
|
||||
TX-STBC-2BY1:0x80::$tx_stbc_2by1 \
|
||||
SU-BEAMFORMER:0x800::$su_beamformer \
|
||||
SU-BEAMFORMEE:0x1000::$su_beamformee \
|
||||
MU-BEAMFORMER:0x80000::$mu_beamformer \
|
||||
MU-BEAMFORMEE:0x100000::$mu_beamformee \
|
||||
VHT-TXOP-PS:0x200000::$vht_txop_ps \
|
||||
HTC-VHT:0x400000::$htc_vht \
|
||||
RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \
|
||||
TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \
|
||||
RX-STBC-1:0x700:0x100:1 \
|
||||
RX-STBC-12:0x700:0x200:1 \
|
||||
RX-STBC-123:0x700:0x300:1 \
|
||||
RX-STBC-1234:0x700:0x400:1 \
|
||||
|
||||
# supported Channel widths
|
||||
vht160_hw=0
|
||||
[ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \
|
||||
vht160_hw=1
|
||||
[ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \
|
||||
vht160_hw=2
|
||||
[ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]"
|
||||
[ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]"
|
||||
|
||||
# maximum MPDU length
|
||||
vht_max_mpdu_hw=3895
|
||||
[ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \
|
||||
vht_max_mpdu_hw=7991
|
||||
[ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \
|
||||
vht_max_mpdu_hw=11454
|
||||
[ "$vht_max_mpdu_hw" != 3895 ] && \
|
||||
vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
|
||||
|
||||
# maximum A-MPDU length exponent
|
||||
vht_max_a_mpdu_len_exp_hw=0
|
||||
[ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=1
|
||||
[ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=2
|
||||
[ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=3
|
||||
[ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=4
|
||||
[ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=5
|
||||
[ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=6
|
||||
[ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \
|
||||
vht_max_a_mpdu_len_exp_hw=7
|
||||
vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]"
|
||||
|
||||
# whether or not the STA supports link adaptation using VHT variant
|
||||
vht_link_adapt_hw=0
|
||||
[ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \
|
||||
vht_link_adapt_hw=2
|
||||
[ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \
|
||||
vht_link_adapt_hw=3
|
||||
[ "$vht_link_adapt_hw" != 0 ] && \
|
||||
vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]"
|
||||
|
||||
[ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N"
|
||||
fi
|
||||
|
||||
hostapd_prepare_device_config "$hostapd_conf_file" nl80211
|
||||
cat >> "$hostapd_conf_file" <<EOF
|
||||
${channel:+channel=$channel}
|
||||
${channel_list:+chanlist=$channel_list}
|
||||
${noscan:+noscan=$noscan}
|
||||
$base_cfg
|
||||
|
||||
EOF
|
||||
json_select ..
|
||||
}
|
||||
|
||||
mac80211_hostapd_setup_bss() {
|
||||
local phy="$1"
|
||||
local ifname="$2"
|
||||
local macaddr="$3"
|
||||
local type="$4"
|
||||
|
||||
hostapd_cfg=
|
||||
append hostapd_cfg "$type=$ifname" "$N"
|
||||
|
||||
hostapd_set_bss_options hostapd_cfg "$vif" || return 1
|
||||
json_get_vars wds dtim_period max_listen_int start_disabled
|
||||
|
||||
set_default wds 0
|
||||
set_default start_disabled 0
|
||||
|
||||
[ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
|
||||
[ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
|
||||
|
||||
cat >> /var/run/hostapd-$phy.conf <<EOF
|
||||
$hostapd_cfg
|
||||
bssid=$macaddr
|
||||
${dtim_period:+dtim_period=$dtim_period}
|
||||
${max_listen_int:+max_listen_interval=$max_listen_int}
|
||||
EOF
|
||||
}
|
||||
|
||||
mac80211_get_addr() {
|
||||
local phy="$1"
|
||||
local idx="$(($2 + 1))"
|
||||
|
||||
head -n $(($macidx + 1)) /sys/class/ieee80211/${phy}/addresses | tail -n1
|
||||
}
|
||||
|
||||
mac80211_generate_mac() {
|
||||
local phy="$1"
|
||||
local id="${macidx:-0}"
|
||||
|
||||
local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)"
|
||||
local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)"
|
||||
|
||||
[ "$mask" = "00:00:00:00:00:00" ] && {
|
||||
mask="ff:ff:ff:ff:ff:ff";
|
||||
|
||||
[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt 1 ] && {
|
||||
addr="$(mac80211_get_addr "$phy" "$id")"
|
||||
[ -n "$addr" ] && {
|
||||
echo "$addr"
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
|
||||
|
||||
local mask1=$1
|
||||
local mask6=$6
|
||||
|
||||
local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
|
||||
|
||||
macidx=$(($id + 1))
|
||||
[ "$((0x$mask1))" -gt 0 ] && {
|
||||
b1="0x$1"
|
||||
[ "$id" -gt 0 ] && \
|
||||
b1=$(($b1 ^ ((($id - 1) << 2) | 0x2)))
|
||||
printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
|
||||
return
|
||||
}
|
||||
|
||||
[ "$((0x$mask6))" -lt 255 ] && {
|
||||
printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
|
||||
return
|
||||
}
|
||||
|
||||
off2=$(( (0x$6 + $id) / 0x100 ))
|
||||
printf "%s:%s:%s:%s:%02x:%02x" \
|
||||
$1 $2 $3 $4 \
|
||||
$(( (0x$5 + $off2) % 0x100 )) \
|
||||
$(( (0x$6 + $id) % 0x100 ))
|
||||
}
|
||||
|
||||
find_phy() {
|
||||
[ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0
|
||||
[ -n "$path" ] && {
|
||||
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
|
||||
case "$(readlink -f /sys/class/ieee80211/$phy/device)" in
|
||||
*$path) return 0;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
[ -n "$macaddr" ] && {
|
||||
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
|
||||
grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0
|
||||
done
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
mac80211_check_ap() {
|
||||
has_ap=1
|
||||
}
|
||||
|
||||
mac80211_iw_interface_add() {
|
||||
local phy="$1"
|
||||
local ifname="$2"
|
||||
local type="$3"
|
||||
local wdsflag="$4"
|
||||
local rc
|
||||
|
||||
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
|
||||
rc="$?"
|
||||
|
||||
[ "$rc" = 233 ] && {
|
||||
# Device might have just been deleted, give the kernel some time to finish cleaning it up
|
||||
sleep 1
|
||||
|
||||
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
|
||||
rc="$?"
|
||||
}
|
||||
|
||||
[ "$rc" = 233 -o "$rc" = 161 ] && {
|
||||
# Device might not support virtual interfaces, so the interface never got deleted in the first place.
|
||||
# Check if the interface already exists, and avoid failing in this case.
|
||||
ip link show dev "$ifname" >/dev/null 2>/dev/null && rc=0
|
||||
}
|
||||
|
||||
[ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
|
||||
return $rc
|
||||
}
|
||||
|
||||
mac80211_prepare_vif() {
|
||||
json_select config
|
||||
|
||||
json_get_vars ifname mode ssid wds powersave macaddr
|
||||
|
||||
[ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}"
|
||||
if_idx=$((${if_idx:-0} + 1))
|
||||
|
||||
set_default wds 0
|
||||
set_default powersave 0
|
||||
|
||||
json_select ..
|
||||
|
||||
[ -n "$macaddr" ] || {
|
||||
macaddr="$(mac80211_generate_mac $phy)"
|
||||
macidx="$(($macidx + 1))"
|
||||
}
|
||||
|
||||
json_add_object data
|
||||
json_add_string ifname "$ifname"
|
||||
json_close_object
|
||||
json_select config
|
||||
|
||||
# It is far easier to delete and create the desired interface
|
||||
case "$mode" in
|
||||
adhoc)
|
||||
mac80211_iw_interface_add "$phy" "$ifname" adhoc || return
|
||||
;;
|
||||
ap)
|
||||
# Hostapd will handle recreating the interface and
|
||||
# subsequent virtual APs belonging to the same PHY
|
||||
if [ -n "$hostapd_ctrl" ]; then
|
||||
type=bss
|
||||
else
|
||||
type=interface
|
||||
fi
|
||||
|
||||
mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
|
||||
|
||||
[ -n "$hostapd_ctrl" ] || {
|
||||
mac80211_iw_interface_add "$phy" "$ifname" __ap || return
|
||||
hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
|
||||
}
|
||||
;;
|
||||
mesh)
|
||||
mac80211_iw_interface_add "$phy" "$ifname" mp || return
|
||||
;;
|
||||
monitor)
|
||||
mac80211_iw_interface_add "$phy" "$ifname" monitor || return
|
||||
;;
|
||||
sta)
|
||||
local wdsflag=
|
||||
staidx="$(($staidx + 1))"
|
||||
[ "$wds" -gt 0 ] && wdsflag="4addr on"
|
||||
mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return
|
||||
[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
|
||||
iw "$ifname" set power_save "$powersave"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$mode" in
|
||||
monitor|mesh)
|
||||
[ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $htmode
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$mode" != "ap" ]; then
|
||||
# ALL ap functionality will be passed to hostapd
|
||||
# All interfaces must have unique mac addresses
|
||||
# which can either be explicitly set in the device
|
||||
# section, or automatically generated
|
||||
ip link set dev "$ifname" address "$macaddr"
|
||||
fi
|
||||
|
||||
json_select ..
|
||||
}
|
||||
|
||||
mac80211_setup_supplicant() {
|
||||
wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1
|
||||
if [ "$mode" = "sta" ]; then
|
||||
wpa_supplicant_add_network "$ifname"
|
||||
else
|
||||
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan"
|
||||
fi
|
||||
wpa_supplicant_run "$ifname" ${hostapd_ctrl:+-H $hostapd_ctrl}
|
||||
}
|
||||
|
||||
mac80211_setup_supplicant_noctl() {
|
||||
wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1
|
||||
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan"
|
||||
wpa_supplicant_run "$ifname"
|
||||
}
|
||||
|
||||
mac80211_setup_adhoc_htmode() {
|
||||
case "$htmode" in
|
||||
VHT20|HT20) ibss_htmode=HT20;;
|
||||
HT40*|VHT40|VHT160)
|
||||
case "$hwmode" in
|
||||
a)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) ibss_htmode="HT40+" ;;
|
||||
0) ibss_htmode="HT40-";;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$htmode" in
|
||||
HT40+) ibss_htmode="HT40+";;
|
||||
HT40-) ibss_htmode="HT40-";;
|
||||
*)
|
||||
if [ "$channel" -lt 7 ]; then
|
||||
ibss_htmode="HT40+"
|
||||
else
|
||||
ibss_htmode="HT40-"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
[ "$auto_channel" -gt 0 ] && ibss_htmode="HT40+"
|
||||
;;
|
||||
VHT80)
|
||||
ibss_htmode="80MHZ"
|
||||
;;
|
||||
NONE|NOHT)
|
||||
ibss_htmode="NOHT"
|
||||
;;
|
||||
*) ibss_htmode="" ;;
|
||||
esac
|
||||
|
||||
}
|
||||
|
||||
mac80211_setup_adhoc() {
|
||||
json_get_vars bssid ssid key mcast_rate
|
||||
|
||||
keyspec=
|
||||
[ "$auth_type" = "wep" ] && {
|
||||
set_default key 1
|
||||
case "$key" in
|
||||
[1234])
|
||||
local idx
|
||||
for idx in 1 2 3 4; do
|
||||
json_get_var ikey "key$idx"
|
||||
|
||||
[ -n "$ikey" ] && {
|
||||
ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")"
|
||||
[ $idx -eq $key ] && ikey="d:$ikey"
|
||||
append keyspec "$ikey"
|
||||
}
|
||||
done
|
||||
;;
|
||||
*)
|
||||
append keyspec "d:0:$(prepare_key_wep "$key")"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
brstr=
|
||||
for br in $basic_rate_list; do
|
||||
wpa_supplicant_add_rate brstr "$br"
|
||||
done
|
||||
|
||||
mcval=
|
||||
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
|
||||
|
||||
iw dev "$ifname" ibss join "$ssid" $freq $ibss_htmode fixed-freq $bssid \
|
||||
beacon-interval $beacon_int \
|
||||
${brstr:+basic-rates $brstr} \
|
||||
${mcval:+mcast-rate $mcval} \
|
||||
${keyspec:+keys $keyspec}
|
||||
}
|
||||
|
||||
mac80211_setup_mesh() {
|
||||
json_get_vars ssid mesh_id mcast_rate
|
||||
|
||||
mcval=
|
||||
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
|
||||
[ -n "$mesh_id" ] && ssid="$mesh_id"
|
||||
|
||||
case "$htmode" in
|
||||
VHT20|HT20) mesh_htmode=HT20;;
|
||||
HT40*|VHT40)
|
||||
case "$hwmode" in
|
||||
a)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) mesh_htmode="HT40+" ;;
|
||||
0) mesh_htmode="HT40-";;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$htmode" in
|
||||
HT40+) mesh_htmode="HT40+";;
|
||||
HT40-) mesh_htmode="HT40-";;
|
||||
*)
|
||||
if [ "$channel" -lt 7 ]; then
|
||||
mesh_htmode="HT40+"
|
||||
else
|
||||
mesh_htmode="HT40-"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
VHT80)
|
||||
mesh_htmode="80Mhz"
|
||||
;;
|
||||
VHT160)
|
||||
mesh_htmode="160Mhz"
|
||||
;;
|
||||
*) mesh_htmode="NOHT" ;;
|
||||
esac
|
||||
iw dev "$ifname" mesh join "$ssid" freq $freq $mesh_htmode \
|
||||
${mcval:+mcast-rate $mcval} \
|
||||
beacon-interval $beacon_int
|
||||
}
|
||||
|
||||
mac80211_setup_vif() {
|
||||
local name="$1"
|
||||
local failed
|
||||
|
||||
json_select data
|
||||
json_get_vars ifname
|
||||
json_select ..
|
||||
|
||||
json_select config
|
||||
json_get_vars mode
|
||||
json_get_var vif_txpower txpower
|
||||
|
||||
ip link set dev "$ifname" up || {
|
||||
wireless_setup_vif_failed IFUP_ERROR
|
||||
json_select ..
|
||||
return
|
||||
}
|
||||
|
||||
set_default vif_txpower "$txpower"
|
||||
[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
|
||||
|
||||
case "$mode" in
|
||||
mesh)
|
||||
wireless_vif_parse_encryption
|
||||
freq="$(get_freq "$phy" "$channel")"
|
||||
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then
|
||||
mac80211_setup_supplicant || failed=1
|
||||
else
|
||||
mac80211_setup_mesh
|
||||
fi
|
||||
for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do
|
||||
json_get_var mp_val "$var"
|
||||
[ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val"
|
||||
done
|
||||
;;
|
||||
adhoc)
|
||||
wireless_vif_parse_encryption
|
||||
mac80211_setup_adhoc_htmode
|
||||
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then
|
||||
freq="$(get_freq "$phy" "$channel")"
|
||||
mac80211_setup_supplicant_noctl || failed=1
|
||||
else
|
||||
mac80211_setup_adhoc
|
||||
fi
|
||||
;;
|
||||
sta)
|
||||
mac80211_setup_supplicant || failed=1
|
||||
;;
|
||||
esac
|
||||
|
||||
json_select ..
|
||||
[ -n "$failed" ] || wireless_add_vif "$name" "$ifname"
|
||||
}
|
||||
|
||||
get_freq() {
|
||||
local phy="$1"
|
||||
local chan="$2"
|
||||
iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
|
||||
}
|
||||
|
||||
chan_is_dfs() {
|
||||
local phy="$1"
|
||||
local chan="$2"
|
||||
iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep -q "MHz.*radar detection"
|
||||
return $!
|
||||
}
|
||||
|
||||
mac80211_interface_cleanup() {
|
||||
local phy="$1"
|
||||
|
||||
for wdev in $(list_phy_interfaces "$phy"); do
|
||||
ip link set dev "$wdev" down 2>/dev/null
|
||||
iw dev "$wdev" del
|
||||
done
|
||||
}
|
||||
|
||||
drv_mac80211_cleanup() {
|
||||
hostapd_common_cleanup
|
||||
}
|
||||
|
||||
drv_mac80211_setup() {
|
||||
json_select config
|
||||
json_get_vars \
|
||||
phy macaddr path \
|
||||
country chanbw distance \
|
||||
txpower antenna_gain \
|
||||
rxantenna txantenna \
|
||||
frag rts beacon_int:100 htmode
|
||||
json_get_values basic_rate_list basic_rate
|
||||
json_select ..
|
||||
|
||||
find_phy || {
|
||||
echo "Could not find PHY for device '$1'"
|
||||
wireless_set_retry 0
|
||||
return 1
|
||||
}
|
||||
|
||||
wireless_set_data phy="$phy"
|
||||
mac80211_interface_cleanup "$phy"
|
||||
|
||||
# convert channel to frequency
|
||||
[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")"
|
||||
|
||||
[ -n "$country" ] && {
|
||||
iw reg get | grep -q "^country $country:" || {
|
||||
iw reg set "$country"
|
||||
sleep 1
|
||||
}
|
||||
}
|
||||
|
||||
hostapd_conf_file="/var/run/hostapd-$phy.conf"
|
||||
|
||||
no_ap=1
|
||||
macidx=0
|
||||
staidx=0
|
||||
|
||||
[ -n "$chanbw" ] && {
|
||||
for file in /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do
|
||||
[ -f "$file" ] && echo "$chanbw" > "$file"
|
||||
done
|
||||
}
|
||||
|
||||
set_default rxantenna all
|
||||
set_default txantenna all
|
||||
set_default distance 0
|
||||
set_default antenna_gain 0
|
||||
|
||||
iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
|
||||
iw phy "$phy" set antenna_gain $antenna_gain
|
||||
iw phy "$phy" set distance "$distance"
|
||||
|
||||
[ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
|
||||
[ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
|
||||
|
||||
has_ap=
|
||||
hostapd_ctrl=
|
||||
for_each_interface "ap" mac80211_check_ap
|
||||
|
||||
rm -f "$hostapd_conf_file"
|
||||
[ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy"
|
||||
|
||||
for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif
|
||||
for_each_interface "ap" mac80211_prepare_vif
|
||||
|
||||
[ -n "$hostapd_ctrl" ] && {
|
||||
/usr/sbin/hostapd -s -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file"
|
||||
ret="$?"
|
||||
wireless_add_process "$(cat /var/run/wifi-$phy.pid)" "/usr/sbin/hostapd" 1
|
||||
[ "$ret" != 0 ] && {
|
||||
wireless_setup_failed HOSTAPD_START_FAILED
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
|
||||
|
||||
wireless_set_up
|
||||
}
|
||||
|
||||
list_phy_interfaces() {
|
||||
local phy="$1"
|
||||
if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then
|
||||
ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null;
|
||||
else
|
||||
ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g'
|
||||
fi
|
||||
}
|
||||
|
||||
drv_mac80211_teardown() {
|
||||
wireless_process_kill_all
|
||||
|
||||
json_select data
|
||||
json_get_vars phy
|
||||
json_select ..
|
||||
|
||||
mac80211_interface_cleanup "$phy"
|
||||
}
|
||||
|
||||
add_driver mac80211
|
132
root/package/kernel/mac80211/files/lib/wifi/mac80211.sh
Normal file
132
root/package/kernel/mac80211/files/lib/wifi/mac80211.sh
Normal file
|
@ -0,0 +1,132 @@
|
|||
#!/bin/sh
|
||||
append DRIVERS "mac80211"
|
||||
|
||||
lookup_phy() {
|
||||
[ -n "$phy" ] && {
|
||||
[ -d /sys/class/ieee80211/$phy ] && return
|
||||
}
|
||||
|
||||
local devpath
|
||||
config_get devpath "$device" path
|
||||
[ -n "$devpath" ] && {
|
||||
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
|
||||
case "$(readlink -f /sys/class/ieee80211/$phy/device)" in
|
||||
*$devpath) return;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
|
||||
[ -n "$macaddr" ] && {
|
||||
for _phy in /sys/class/ieee80211/*; do
|
||||
[ -e "$_phy" ] || continue
|
||||
|
||||
[ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue
|
||||
phy="${_phy##*/}"
|
||||
return
|
||||
done
|
||||
}
|
||||
phy=
|
||||
return
|
||||
}
|
||||
|
||||
find_mac80211_phy() {
|
||||
local device="$1"
|
||||
|
||||
config_get phy "$device" phy
|
||||
lookup_phy
|
||||
[ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
|
||||
echo "PHY for wifi device $1 not found"
|
||||
return 1
|
||||
}
|
||||
config_set "$device" phy "$phy"
|
||||
|
||||
config_get macaddr "$device" macaddr
|
||||
[ -z "$macaddr" ] && {
|
||||
config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_mac80211_device() {
|
||||
config_get phy "$1" phy
|
||||
[ -z "$phy" ] && {
|
||||
find_mac80211_phy "$1" >/dev/null || return 0
|
||||
config_get phy "$1" phy
|
||||
}
|
||||
[ "$phy" = "$dev" ] && found=1
|
||||
}
|
||||
|
||||
detect_mac80211() {
|
||||
devidx=0
|
||||
config_load wireless
|
||||
while :; do
|
||||
config_get type "radio$devidx" type
|
||||
[ -n "$type" ] || break
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
|
||||
for _dev in /sys/class/ieee80211/*; do
|
||||
[ -e "$_dev" ] || continue
|
||||
|
||||
dev="${_dev##*/}"
|
||||
|
||||
found=0
|
||||
config_foreach check_mac80211_device wifi-device
|
||||
[ "$found" -gt 0 ] && continue
|
||||
|
||||
mode_band="g"
|
||||
channel="11"
|
||||
htmode=""
|
||||
ht_capab=""
|
||||
|
||||
iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20
|
||||
|
||||
iw phy "$dev" info | grep -q '5180 MHz' && {
|
||||
mode_band="a"
|
||||
channel="36"
|
||||
iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80"
|
||||
}
|
||||
|
||||
[ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode"
|
||||
|
||||
if [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${dev} ]; then
|
||||
path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
|
||||
else
|
||||
path=""
|
||||
fi
|
||||
macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)"
|
||||
if [ -n "$path" ]; then
|
||||
path="${path##/sys/devices/}"
|
||||
case "$path" in
|
||||
platform*/pci*) path="${path##platform/}";;
|
||||
esac
|
||||
dev_id="set wireless.radio${devidx}.path='$path'"
|
||||
elif [ "$macaddr" != "00:00:00:00:00:00" ]; then
|
||||
dev_id="set wireless.radio${devidx}.macaddr=$macaddr"
|
||||
else
|
||||
dev_id="set wireless.radio${devidx}.phy=$dev"
|
||||
fi
|
||||
|
||||
uci -q batch <<-EOF
|
||||
set wireless.radio${devidx}=wifi-device
|
||||
set wireless.radio${devidx}.type=mac80211
|
||||
set wireless.radio${devidx}.channel=${channel}
|
||||
set wireless.radio${devidx}.hwmode=11${mode_band}
|
||||
${dev_id}
|
||||
${ht_capab}
|
||||
set wireless.radio${devidx}.disabled=1
|
||||
|
||||
set wireless.default_radio${devidx}=wifi-iface
|
||||
set wireless.default_radio${devidx}.device=radio${devidx}
|
||||
set wireless.default_radio${devidx}.network=lan
|
||||
set wireless.default_radio${devidx}.mode=ap
|
||||
set wireless.default_radio${devidx}.ssid=OpenWrt
|
||||
set wireless.default_radio${devidx}.encryption=none
|
||||
EOF
|
||||
uci -q commit wireless
|
||||
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
}
|
5
root/package/kernel/mac80211/files/mac80211.hotplug
Normal file
5
root/package/kernel/mac80211/files/mac80211.hotplug
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ "${ACTION}" = "add" ] && {
|
||||
/sbin/wifi config
|
||||
}
|
14
root/package/kernel/mac80211/patches/000-fix_kconfig.patch
Normal file
14
root/package/kernel/mac80211/patches/000-fix_kconfig.patch
Normal file
|
@ -0,0 +1,14 @@
|
|||
--- a/kconf/Makefile
|
||||
+++ b/kconf/Makefile
|
||||
@@ -1,9 +1,9 @@
|
||||
-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
+CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
|
||||
|
||||
LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
|
||||
|
||||
conf: conf.o zconf.tab.o
|
||||
-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
|
||||
+mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
|
||||
mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
|
||||
mconf: CFLAGS += $(mconf_CFLAGS)
|
||||
|
167
root/package/kernel/mac80211/patches/001-fix_build.patch
Normal file
167
root/package/kernel/mac80211/patches/001-fix_build.patch
Normal file
|
@ -0,0 +1,167 @@
|
|||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
ifeq ($(KERNELRELEASE),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
-SHELL := /bin/bash
|
||||
+SHELL := /usr/bin/env bash
|
||||
BACKPORT_DIR := $(shell pwd)
|
||||
|
||||
KMODDIR ?= updates
|
||||
@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
|
||||
KERNEL_CONFIG := $(KLIB_BUILD)/.config
|
||||
KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
|
||||
CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
|
||||
+STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
|
||||
|
||||
export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG
|
||||
|
||||
@@ -36,7 +37,8 @@ mrproper:
|
||||
@rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
|
||||
@rm -f backport-include/backport/autoconf.h
|
||||
|
||||
-.DEFAULT:
|
||||
+.SILENT: $(STAMP_KERNEL_CONFIG)
|
||||
+$(STAMP_KERNEL_CONFIG):
|
||||
@set -e ; test -f local-symbols || ( \
|
||||
echo "/--------------" ;\
|
||||
echo "| You shouldn't run make in the backports tree, but only in" ;\
|
||||
@@ -60,57 +62,61 @@ mrproper:
|
||||
echo "| (that isn't currently running.)" ;\
|
||||
echo "\\--" ;\
|
||||
false)
|
||||
- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\
|
||||
- then \
|
||||
- echo -n "Generating local configuration database from kernel ..." ;\
|
||||
- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
- while read l ; do \
|
||||
- if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- l=$${l:7} ;\
|
||||
- n=$${l%%=*} ;\
|
||||
- v=$${l#*=} ;\
|
||||
- if [ "$$v" = "m" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' tristate' ;\
|
||||
- elif [ "$$v" = "y" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' bool' ;\
|
||||
- else \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- echo " default $$v" ;\
|
||||
- echo "" ;\
|
||||
- done \
|
||||
- ) > Kconfig.kernel ;\
|
||||
- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \
|
||||
- sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\
|
||||
- test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
- test "$$kver" != "" ;\
|
||||
- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\
|
||||
- print=0 ;\
|
||||
- for v in $$kvers ; do \
|
||||
- if [ "$$print" = "1" ] ; then \
|
||||
- echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
- echo " def_bool y" ;\
|
||||
- fi ;\
|
||||
- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
- done > Kconfig.versions ;\
|
||||
- # RHEL as well, sadly we need to grep for it ;\
|
||||
- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
- echo " def_bool y" ;\
|
||||
- done >> Kconfig.versions ;\
|
||||
- echo " done." ;\
|
||||
- fi ;\
|
||||
- echo "$(CONFIG_MD5)" > .kernel_config_md5
|
||||
+ @rm -f .kernel_config_md5_*
|
||||
+ @touch $@
|
||||
+
|
||||
+Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols
|
||||
+ @printf "Generating local configuration database from kernel ..."
|
||||
+ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
+ while read l ; do \
|
||||
+ if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ l=$${l:7} ;\
|
||||
+ n=$${l%%=*} ;\
|
||||
+ v=$${l#*=} ;\
|
||||
+ if [ "$$v" = "m" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' tristate' ;\
|
||||
+ elif [ "$$v" = "y" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' bool' ;\
|
||||
+ else \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ echo " default $$v" ;\
|
||||
+ echo "" ;\
|
||||
+ done \
|
||||
+ ) > $@
|
||||
+ @echo " done."
|
||||
+
|
||||
+Kconfig.versions: Kconfig.kernel
|
||||
+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \
|
||||
+ sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\
|
||||
+ test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
+ test "$$kver" != "" ;\
|
||||
+ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\
|
||||
+ print=0 ;\
|
||||
+ for v in $$kvers ; do \
|
||||
+ if [ "$$print" = "1" ] ; then \
|
||||
+ echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ fi ;\
|
||||
+ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
+ done > $@
|
||||
+ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
+ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ done >> $@
|
||||
+
|
||||
+.DEFAULT:
|
||||
+ @$(MAKE) Kconfig.versions
|
||||
@$(MAKE) -f Makefile.real "$@"
|
||||
|
||||
.PHONY: defconfig-help
|
||||
--- a/Makefile.real
|
||||
+++ b/Makefile.real
|
||||
@@ -59,7 +59,7 @@ defconfig-%::
|
||||
|
||||
backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel
|
||||
@$(MAKE) oldconfig
|
||||
- @echo -n "Building backport-include/backport/autoconf.h ..."
|
||||
+ @printf "Building backport-include/backport/autoconf.h ..."
|
||||
@grep -f local-symbols .config | ( \
|
||||
echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
echo "#define COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c
|
||||
esac ;\
|
||||
done ;\
|
||||
echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\
|
||||
- ) > backport-include/backport/autoconf.h
|
||||
+ ) > $@.new
|
||||
+ @if cmp -s $@ $@.new; then \
|
||||
+ rm -f $@.new; \
|
||||
+ else \
|
||||
+ mv $@.new $@; \
|
||||
+ fi
|
||||
@echo " done."
|
||||
|
||||
.PHONY: modules
|
|
@ -0,0 +1,64 @@
|
|||
--- a/kconf/conf.c
|
||||
+++ b/kconf/conf.c
|
||||
@@ -594,40 +594,12 @@ int main(int ac, char **av)
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
case olddefconfig:
|
||||
- conf_read(NULL);
|
||||
- break;
|
||||
case allnoconfig:
|
||||
case allyesconfig:
|
||||
case allmodconfig:
|
||||
case alldefconfig:
|
||||
case randconfig:
|
||||
- name = getenv("KCONFIG_ALLCONFIG");
|
||||
- if (!name)
|
||||
- break;
|
||||
- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
|
||||
- if (conf_read_simple(name, S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** Can't read seed configuration \"%s\"!\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- switch (input_mode) {
|
||||
- case allnoconfig: name = "allno.config"; break;
|
||||
- case allyesconfig: name = "allyes.config"; break;
|
||||
- case allmodconfig: name = "allmod.config"; break;
|
||||
- case alldefconfig: name = "alldef.config"; break;
|
||||
- case randconfig: name = "allrandom.config"; break;
|
||||
- default: break;
|
||||
- }
|
||||
- if (conf_read_simple(name, S_DEF_USER) &&
|
||||
- conf_read_simple("all.config", S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
+ conf_read(NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
--- a/kconf/confdata.c
|
||||
+++ b/kconf/confdata.c
|
||||
@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
}
|
||||
bool has_changed = false;
|
||||
|
||||
+ sym_clear_all_valid();
|
||||
+
|
||||
for_all_symbols(i, sym) {
|
||||
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
|
||||
continue;
|
||||
@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
|
||||
}
|
||||
|
||||
- sym_clear_all_valid();
|
||||
-
|
||||
/*
|
||||
* We have different type of choice blocks.
|
||||
* If curr.tri equals to mod then we can select several
|
|
@ -0,0 +1,34 @@
|
|||
--- a/compat/main.c
|
||||
+++ b/compat/main.c
|
||||
@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
|
||||
#error "You need a CPTCFG_VERSION"
|
||||
#endif
|
||||
|
||||
-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
|
||||
-
|
||||
-module_param(backported_kernel_name, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_name,
|
||||
- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
|
||||
-
|
||||
-#ifdef BACKPORTS_GIT_TRACKED
|
||||
-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
|
||||
-module_param(backports_tracker_id, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_tracker_id,
|
||||
- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
|
||||
-#else
|
||||
-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
|
||||
-static char *backports_version = CPTCFG_VERSION;
|
||||
-
|
||||
-module_param(backported_kernel_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_version,
|
||||
- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
|
||||
-
|
||||
-module_param(backports_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_version,
|
||||
- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
void backport_dependency_symbol(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
--- a/backport-include/linux/kconfig.h
|
||||
+++ b/backport-include/linux/kconfig.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#include_next <linux/kconfig.h>
|
||||
#endif
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
|
||||
+
|
||||
#ifndef __ARG_PLACEHOLDER_1
|
||||
#define __ARG_PLACEHOLDER_1 0,
|
||||
#define config_enabled(cfg) _config_enabled(cfg)
|
||||
@@ -16,6 +18,7 @@
|
||||
* 3.1 - 3.3 had a broken version of this, so undef
|
||||
* (they didn't have __ARG_PLACEHOLDER_1)
|
||||
*/
|
||||
+
|
||||
#undef IS_ENABLED
|
||||
#define IS_ENABLED(option) \
|
||||
(config_enabled(option) || config_enabled(option##_MODULE))
|
||||
@@ -31,6 +34,8 @@
|
||||
#undef IS_BUILTIN
|
||||
#define IS_BUILTIN(option) config_enabled(option)
|
||||
|
||||
+#endif
|
||||
+
|
||||
#ifndef IS_REACHABLE
|
||||
/*
|
||||
* IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled
|
|
@ -0,0 +1,11 @@
|
|||
--- a/compat/Makefile
|
||||
+++ b/compat/Makefile
|
||||
@@ -70,8 +70,6 @@ quiet_cmd_build_OID_registry = GEN $
|
||||
cmd_build_OID_registry = perl $(src)/build_OID_registry $< $@
|
||||
compat-$(CPTCFG_BPAUTO_ASN1_DECODER) += lib-asn1_decoder.o
|
||||
compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += lib-oid_registry.o
|
||||
-skcipher-objs += crypto-skcipher.o
|
||||
-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o
|
||||
compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o
|
||||
cordic-objs += lib-cordic.o
|
||||
obj-$(CPTCFG_BPAUTO_BUILD_CORDIC) += cordic.o
|
|
@ -0,0 +1,10 @@
|
|||
--- a/compat/backport-4.12.c
|
||||
+++ b/compat/backport-4.12.c
|
||||
@@ -225,6 +225,7 @@ int bp_extack_genl_register_family(struc
|
||||
|
||||
/* copy this since the family might access it directly */
|
||||
family->attrbuf = copy->family.attrbuf;
|
||||
+ family->mcgrp_offset = copy->family.mcgrp_offset;
|
||||
|
||||
mutex_lock(&copies_mutex);
|
||||
list_add_tail(©->list, &copies_list);
|
|
@ -0,0 +1,11 @@
|
|||
--- a/backport-include/linux/verification.h
|
||||
+++ b/backport-include/linux/verification.h
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __BP_VERIFICATION_H
|
||||
#define __BP_VERIFICATION_H
|
||||
#include <linux/version.h>
|
||||
-#ifndef CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION
|
||||
+#if LINUX_VERSION_IS_GEQ(4,7,0) && !defined(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION)
|
||||
#include_next <linux/verification.h>
|
||||
#else
|
||||
#include <linux/key.h>
|
|
@ -0,0 +1,10 @@
|
|||
--- a/compat/backport-4.12.c
|
||||
+++ b/compat/backport-4.12.c
|
||||
@@ -224,6 +224,7 @@ int bp_extack_genl_register_family(struc
|
||||
}
|
||||
|
||||
/* copy this since the family might access it directly */
|
||||
+ family->id = copy->family.id;
|
||||
family->attrbuf = copy->family.attrbuf;
|
||||
family->mcgrp_offset = copy->family.mcgrp_offset;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
--- a/backport-include/linux/rfkill.h
|
||||
+++ b/backport-include/linux/rfkill.h
|
||||
@@ -2,6 +2,12 @@
|
||||
#define __COMPAT_RFKILL_H
|
||||
#include <linux/version.h>
|
||||
|
||||
+#undef CONFIG_RFKILL
|
||||
+#undef CONFIG_RFKILL_FULL
|
||||
+#undef CONFIG_RFKILL_LEDS
|
||||
+#undef CONFIG_RFKILL_MODULE
|
||||
+#undef CONFIG_RFKILL_FULL_MODULE
|
||||
+
|
||||
#if LINUX_VERSION_IS_GEQ(3,10,0)
|
||||
#include_next <linux/rfkill.h>
|
||||
#else
|
|
@ -0,0 +1,11 @@
|
|||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for the output source package
|
||||
#
|
||||
|
||||
-ifeq ($(KERNELRELEASE),)
|
||||
+ifeq ($(KERNELVERSION),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
SHELL := /usr/bin/env bash
|
34
root/package/kernel/mac80211/patches/015-ipw200-mtu.patch
Normal file
34
root/package/kernel/mac80211/patches/015-ipw200-mtu.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
@@ -11506,6 +11506,15 @@ static const struct attribute_group ipw_
|
||||
.attrs = ipw_sysfs_entries,
|
||||
};
|
||||
|
||||
+#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
+static int __change_mtu(struct net_device *ndev, int new_mtu){
|
||||
+ if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN)
|
||||
+ return -EINVAL;
|
||||
+ ndev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef CPTCFG_IPW2200_PROMISCUOUS
|
||||
static int ipw_prom_open(struct net_device *dev)
|
||||
{
|
||||
@@ -11554,15 +11563,6 @@ static netdev_tx_t ipw_prom_hard_start_x
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
-#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
-static int __change_mtu(struct net_device *ndev, int new_mtu){
|
||||
- if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN)
|
||||
- return -EINVAL;
|
||||
- ndev->mtu = new_mtu;
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static const struct net_device_ops ipw_prom_netdev_ops = {
|
||||
#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
.ndo_change_mtu = __change_mtu,
|
|
@ -0,0 +1,47 @@
|
|||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -225,36 +225,37 @@ config RT2800SOC
|
||||
|
||||
|
||||
config RT2800_LIB
|
||||
- tristate
|
||||
+ tristate "RT2800 USB/PCI support"
|
||||
depends on m
|
||||
|
||||
config RT2800_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2800 MMIO support"
|
||||
depends on m
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2800_LIB
|
||||
|
||||
config RT2X00_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2x00 MMIO support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_PCI
|
||||
- tristate
|
||||
+ tristate "RT2x00 PCI support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_SOC
|
||||
- tristate
|
||||
+ tristate "RT2x00 SoC support"
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_USB
|
||||
- tristate
|
||||
+ tristate "RT2x00 USB support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB
|
||||
- tristate
|
||||
+ tristate "RT2x00 support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_FIRMWARE
|
|
@ -0,0 +1,9 @@
|
|||
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
@@ -1,5 +1,5 @@
|
||||
config BRCMUTIL
|
||||
- tristate
|
||||
+ tristate "Broadcom 802.11 driver utility functions"
|
||||
depends on m
|
||||
|
||||
config BRCMSMAC
|
|
@ -0,0 +1,30 @@
|
|||
--- a/net/wireless/Kconfig
|
||||
+++ b/net/wireless/Kconfig
|
||||
@@ -181,7 +181,7 @@ config CFG80211_WEXT_EXPORT
|
||||
wext compatibility symbols to be exported.
|
||||
|
||||
config LIB80211
|
||||
- tristate
|
||||
+ tristate "lib80211"
|
||||
depends on m
|
||||
default n
|
||||
help
|
||||
@@ -191,15 +191,15 @@ config LIB80211
|
||||
Drivers should select this themselves if needed.
|
||||
|
||||
config LIB80211_CRYPT_WEP
|
||||
- tristate
|
||||
+ tristate "lib80211 WEP support"
|
||||
depends on m
|
||||
|
||||
config LIB80211_CRYPT_CCMP
|
||||
- tristate
|
||||
+ tristate "lib80211 CCMP support"
|
||||
depends on m
|
||||
|
||||
config LIB80211_CRYPT_TKIP
|
||||
- tristate
|
||||
+ tristate "lib80211 TKIP support"
|
||||
depends on m
|
||||
|
||||
config LIB80211_DEBUG
|
132
root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
Normal file
132
root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
Normal file
|
@ -0,0 +1,132 @@
|
|||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -388,45 +388,6 @@ USB_IPHETH=
|
||||
USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
USB_NET_CH9200=
|
||||
-SSB_POSSIBLE=
|
||||
-SSB=
|
||||
-SSB_SPROM=
|
||||
-SSB_BLOCKIO=
|
||||
-SSB_PCIHOST_POSSIBLE=
|
||||
-SSB_PCIHOST=
|
||||
-SSB_B43_PCI_BRIDGE=
|
||||
-SSB_PCMCIAHOST_POSSIBLE=
|
||||
-SSB_PCMCIAHOST=
|
||||
-SSB_SDIOHOST_POSSIBLE=
|
||||
-SSB_SDIOHOST=
|
||||
-SSB_HOST_SOC=
|
||||
-SSB_SILENT=
|
||||
-SSB_DEBUG=
|
||||
-SSB_SERIAL=
|
||||
-SSB_DRIVER_PCICORE_POSSIBLE=
|
||||
-SSB_DRIVER_PCICORE=
|
||||
-SSB_PCICORE_HOSTMODE=
|
||||
-SSB_DRIVER_MIPS=
|
||||
-SSB_SFLASH=
|
||||
-SSB_EMBEDDED=
|
||||
-SSB_DRIVER_EXTIF=
|
||||
-SSB_DRIVER_GIGE=
|
||||
-SSB_DRIVER_GPIO=
|
||||
-BCMA_POSSIBLE=
|
||||
-BCMA=
|
||||
-BCMA_BLOCKIO=
|
||||
-BCMA_HOST_PCI_POSSIBLE=
|
||||
-BCMA_HOST_PCI=
|
||||
-BCMA_HOST_SOC=
|
||||
-BCMA_DRIVER_PCI=
|
||||
-BCMA_DRIVER_PCI_HOSTMODE=
|
||||
-BCMA_DRIVER_MIPS=
|
||||
-BCMA_PFLASH=
|
||||
-BCMA_SFLASH=
|
||||
-BCMA_NFLASH=
|
||||
-BCMA_DRIVER_GMAC_CMN=
|
||||
-BCMA_DRIVER_GPIO=
|
||||
-BCMA_DEBUG=
|
||||
NFC=
|
||||
NFC_DIGITAL=
|
||||
NFC_NCI=
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2876,7 +2876,7 @@ static struct ssb_device *b43_ssb_gpio_d
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
|
||||
#else
|
||||
return bus->chipco.dev;
|
||||
@@ -4893,7 +4893,7 @@ static int b43_wireless_core_init(struct
|
||||
}
|
||||
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
|
||||
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
|
||||
-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE)
|
||||
+#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE)
|
||||
if (dev->dev->bus_type == B43_BUS_SSB &&
|
||||
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
|
||||
dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
|
||||
--- a/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
@@ -1937,7 +1937,7 @@ static int b43legacy_gpio_init(struct b4
|
||||
if (dev->dev->id.revision >= 2)
|
||||
mask |= 0x0010; /* FIXME: This is redundant. */
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
@@ -1956,7 +1956,7 @@ static void b43legacy_gpio_cleanup(struc
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct ssb_device *gpiodev, *pcidev = NULL;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
@@ -42,6 +42,6 @@ brcmsmac-y := \
|
||||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
-brcmsmac-$(CPTCFG_BCMA_DRIVER_GPIO) += led.o
|
||||
+brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
|
||||
|
||||
obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
@@ -22,7 +22,7 @@ struct brcms_led {
|
||||
bool active_low;
|
||||
};
|
||||
|
||||
-#ifdef CPTCFG_BCMA_DRIVER_GPIO
|
||||
+#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
--- a/Kconfig.sources
|
||||
+++ b/Kconfig.sources
|
||||
@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele
|
||||
#source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
|
||||
source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
|
||||
|
||||
-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
|
||||
-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
|
||||
-
|
||||
source "$BACKPORT_DIR/net/nfc/Kconfig"
|
||||
|
||||
#source "$BACKPORT_DIR/drivers/media/Kconfig"
|
||||
--- a/Makefile.kernel
|
||||
+++ b/Makefile.kernel
|
||||
@@ -42,8 +42,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
|
||||
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
|
||||
#obj-$(CPTCFG_BT) += net/bluetooth/
|
||||
#obj-$(CPTCFG_BT) += drivers/bluetooth/
|
||||
-obj-$(CPTCFG_SSB) += drivers/ssb/
|
||||
-obj-$(CPTCFG_BCMA) += drivers/bcma/
|
||||
#obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
|
||||
obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
|
||||
obj-$(CPTCFG_NFC) += net/nfc/
|
|
@ -0,0 +1,9 @@
|
|||
--- a/drivers/net/wireless/ath/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/Kconfig
|
||||
@@ -1,5 +1,5 @@
|
||||
config ATH_COMMON
|
||||
- tristate
|
||||
+ tristate "ath.ko"
|
||||
depends on m
|
||||
|
||||
config WLAN_VENDOR_ATH
|
|
@ -0,0 +1,47 @@
|
|||
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
@@ -65,6 +65,12 @@ config ATH10K_TRACING
|
||||
---help---
|
||||
Select this to ath10k use tracing infrastructure.
|
||||
|
||||
+config ATH10K_THERMAL
|
||||
+ bool "Atheros ath10k thermal monitoring support"
|
||||
+ depends on THERMAL
|
||||
+ ---help---
|
||||
+ Select this to ath10k use hwmon for thermal measurement.
|
||||
+
|
||||
config ATH10K_DFS_CERTIFIED
|
||||
bool "Atheros DFS support for certified platforms"
|
||||
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
|
||||
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
||||
@@ -17,7 +17,7 @@ ath10k_core-y += mac.o \
|
||||
ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o
|
||||
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
||||
-ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
||||
+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
||||
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
|
||||
ath10k_core-$(CONFIG_PM) += wow.o
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
@@ -36,7 +36,7 @@ struct ath10k_thermal {
|
||||
int temperature;
|
||||
};
|
||||
|
||||
-#if IS_REACHABLE(CONFIG_THERMAL)
|
||||
+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
|
||||
int ath10k_thermal_register(struct ath10k *ar);
|
||||
void ath10k_thermal_unregister(struct ath10k *ar);
|
||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -139,6 +139,7 @@ ATH10K_SDIO=
|
||||
ATH10K_USB=
|
||||
ATH10K_DEBUG=
|
||||
ATH10K_DEBUGFS=
|
||||
+ATH10K_THERMAL=
|
||||
ATH10K_TRACING=
|
||||
ATH10K_DFS_CERTIFIED=
|
||||
WCN36XX=
|
|
@ -0,0 +1,111 @@
|
|||
From d06f26c5c8a41f246a9c40862a77a55725cedbd3 Mon Sep 17 00:00:00 2001
|
||||
From: Sven Eckelmann <sven.eckelmann@openmesh.com>
|
||||
Date: Fri, 8 Dec 2017 11:37:42 +0100
|
||||
Subject: ath10k: search DT for qcom,ath10k-calibration-variant
|
||||
|
||||
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
|
||||
board data file is identified on QCA4019 using bus, bmi-chip-id and
|
||||
bmi-board-id.
|
||||
|
||||
The problem, however, can occur when the (default) board data file cannot
|
||||
fulfill with the vendor requirements and it is necessary to use a different
|
||||
board data file.
|
||||
|
||||
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
|
||||
Something similar has to be provided for systems without SMBIOS but with
|
||||
device trees. No solution was specified by QCA and therefore a new one has
|
||||
to be found for ath10k.
|
||||
|
||||
The device tree requires addition strings to define the variant name
|
||||
|
||||
wifi@a000000 {
|
||||
status = "okay";
|
||||
qcom,ath10k-calibration-variant = "RT-AC58U";
|
||||
};
|
||||
|
||||
wifi@a800000 {
|
||||
status = "okay";
|
||||
qcom,ath10k-calibration-variant = "RT-AC58U";
|
||||
};
|
||||
|
||||
This would create the boarddata identifiers for the board-2.bin search
|
||||
|
||||
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
|
||||
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
|
||||
|
||||
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.c | 40 ++++++++++++++++++++++++++++------
|
||||
1 file changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -860,6 +860,28 @@ static int ath10k_core_check_smbios(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ath10k_core_check_dt(struct ath10k *ar)
|
||||
+{
|
||||
+ struct device_node *node;
|
||||
+ const char *variant = NULL;
|
||||
+
|
||||
+ node = ar->dev->of_node;
|
||||
+ if (!node)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ of_property_read_string(node, "qcom,ath10k-calibration-variant",
|
||||
+ &variant);
|
||||
+ if (!variant)
|
||||
+ return -ENODATA;
|
||||
+
|
||||
+ if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0)
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
+ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
|
||||
+ variant);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ath10k_download_and_run_otp(struct ath10k *ar)
|
||||
{
|
||||
u32 result, address = ar->hw_params.patch_load_addr;
|
||||
@@ -1231,19 +1253,19 @@ static int ath10k_core_create_board_name
|
||||
/* strlen(',variant=') + strlen(ar->id.bdf_ext) */
|
||||
char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
|
||||
|
||||
+ if (ar->id.bdf_ext[0] != '\0')
|
||||
+ scnprintf(variant, sizeof(variant), ",variant=%s",
|
||||
+ ar->id.bdf_ext);
|
||||
+
|
||||
if (ar->id.bmi_ids_valid) {
|
||||
scnprintf(name, name_len,
|
||||
- "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
|
||||
+ "bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s",
|
||||
ath10k_bus_str(ar->hif.bus),
|
||||
ar->id.bmi_chip_id,
|
||||
- ar->id.bmi_board_id);
|
||||
+ ar->id.bmi_board_id, variant);
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (ar->id.bdf_ext[0] != '\0')
|
||||
- scnprintf(variant, sizeof(variant), ",variant=%s",
|
||||
- ar->id.bdf_ext);
|
||||
-
|
||||
scnprintf(name, name_len,
|
||||
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
|
||||
ath10k_bus_str(ar->hif.bus),
|
||||
@@ -2343,7 +2365,11 @@ static int ath10k_core_probe_fw(struct a
|
||||
|
||||
ret = ath10k_core_check_smbios(ar);
|
||||
if (ret)
|
||||
- ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n");
|
||||
+
|
||||
+ ret = ath10k_core_check_dt(ar);
|
||||
+ if (ret)
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");
|
||||
|
||||
ret = ath10k_core_fetch_board_file(ar);
|
||||
if (ret) {
|
|
@ -0,0 +1,36 @@
|
|||
From 606204bb863fa3b0bb54929d79b4dc46338f9180 Mon Sep 17 00:00:00 2001
|
||||
From: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Date: Tue, 27 Mar 2018 11:26:46 +0300
|
||||
Subject: [PATCH] ath10k: suppress "Unknown eventid: 36925" warnings
|
||||
|
||||
FW has Smart Logging feature enabled by default for detecting failures
|
||||
and processing FATAL_CONDITION_EVENTID (36925 - 0x903D) back to host.
|
||||
|
||||
Since ath10k doesn't implement the Smart Logging and FATAL CONDITION
|
||||
EVENT processing yet, suppressing the unknown event ID warning by moving
|
||||
this under ATH10K_DBG_WMI.
|
||||
|
||||
Simulated the same issue by having associated STA powered off when
|
||||
ping flood was running from AP backbone. This triggerd STA KICKOUT
|
||||
in AP followed by FATAL CONDITION event 36925.
|
||||
|
||||
Issue was reproduced and verified in below DUT
|
||||
------------------------------------------------
|
||||
AP mode of OpenWRT QCA9984 running 6.0.8 with FW ver 10.4-3.5.3-00053
|
||||
|
||||
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -5462,6 +5462,7 @@ static void ath10k_wmi_10_4_op_rx(struct
|
||||
case WMI_10_4_WOW_WAKEUP_HOST_EVENTID:
|
||||
case WMI_10_4_PEER_RATECODE_LIST_EVENTID:
|
||||
case WMI_10_4_WDS_PEER_EVENTID:
|
||||
+ case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID:
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"received event id %d not implemented\n", id);
|
||||
break;
|
|
@ -0,0 +1,45 @@
|
|||
From patchwork Mon May 28 11:25:06 2018
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: Revert "rt2800: use TXOP_BACKOFF for probe frames"
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
X-Patchwork-Id: 10431861
|
||||
Message-Id: <1527506706-6488-1-git-send-email-sgruszka@redhat.com>
|
||||
To: linux-wireless@vger.kernel.org
|
||||
Date: Mon, 28 May 2018 13:25:06 +0200
|
||||
|
||||
This reverts commit fb47ada8dc3c30c8e7b415da155742b49536c61e.
|
||||
|
||||
In some situations when we set TXOP_BACKOFF, the probe frame is
|
||||
not sent at all. What it worse then sending probe frame as part
|
||||
of AMPDU and can degrade 11n performance to 11g rates.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
@@ -372,16 +372,15 @@ static void rt2x00queue_create_tx_descri
|
||||
|
||||
/*
|
||||
* Determine IFS values
|
||||
- * - Use TXOP_BACKOFF for probe and management frames except beacons
|
||||
+ * - Use TXOP_BACKOFF for management frames except beacons
|
||||
* - Use TXOP_SIFS for fragment bursts
|
||||
* - Use TXOP_HTTXOP for everything else
|
||||
*
|
||||
* Note: rt2800 devices won't use CTS protection (if used)
|
||||
* for frames not transmitted with TXOP_HTTXOP
|
||||
*/
|
||||
- if ((ieee80211_is_mgmt(hdr->frame_control) &&
|
||||
- !ieee80211_is_beacon(hdr->frame_control)) ||
|
||||
- (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
|
||||
+ if (ieee80211_is_mgmt(hdr->frame_control) &&
|
||||
+ !ieee80211_is_beacon(hdr->frame_control))
|
||||
txdesc->u.ht.txop = TXOP_BACKOFF;
|
||||
else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
|
||||
txdesc->u.ht.txop = TXOP_SIFS;
|
|
@ -0,0 +1,705 @@
|
|||
--- a/net/mac80211/Makefile
|
||||
+++ b/net/mac80211/Makefile
|
||||
@@ -6,7 +6,6 @@ mac80211-y := \
|
||||
driver-ops.o \
|
||||
sta_info.o \
|
||||
wep.o \
|
||||
- aead_api.o \
|
||||
wpa.o \
|
||||
scan.o offchannel.o \
|
||||
ht.o agg-tx.o agg-rx.o \
|
||||
@@ -16,8 +15,8 @@ mac80211-y := \
|
||||
rate.o \
|
||||
michael.o \
|
||||
tkip.o \
|
||||
+ aes_ccm.o \
|
||||
aes_cmac.o \
|
||||
- aes_gmac.o \
|
||||
fils_aead.o \
|
||||
cfg.o \
|
||||
ethtool.o \
|
||||
--- a/net/mac80211/aead_api.c
|
||||
+++ /dev/null
|
||||
@@ -1,115 +0,0 @@
|
||||
-/*
|
||||
- * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
- * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
- * Copyright 2014-2015, Qualcomm Atheros, Inc.
|
||||
- *
|
||||
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
- *
|
||||
- * This program is free software; you can redistribute it and/or modify
|
||||
- * it under the terms of the GNU General Public License version 2 as
|
||||
- * published by the Free Software Foundation.
|
||||
- */
|
||||
-
|
||||
-#include <linux/kernel.h>
|
||||
-#include <linux/types.h>
|
||||
-#include <linux/err.h>
|
||||
-#include <linux/scatterlist.h>
|
||||
-#include <crypto/aead.h>
|
||||
-
|
||||
-#include "aead_api.h"
|
||||
-
|
||||
-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
|
||||
- u8 *data, size_t data_len, u8 *mic)
|
||||
-{
|
||||
- size_t mic_len = crypto_aead_authsize(tfm);
|
||||
- struct scatterlist sg[3];
|
||||
- struct aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- __aad = (u8 *)aead_req + reqsize;
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- sg_init_table(sg, 3);
|
||||
- sg_set_buf(&sg[0], __aad, aad_len);
|
||||
- sg_set_buf(&sg[1], data, data_len);
|
||||
- sg_set_buf(&sg[2], mic, mic_len);
|
||||
-
|
||||
- aead_request_set_tfm(aead_req, tfm);
|
||||
- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
|
||||
- aead_request_set_ad(aead_req, sg[0].length);
|
||||
-
|
||||
- crypto_aead_encrypt(aead_req);
|
||||
- kzfree(aead_req);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
|
||||
- u8 *data, size_t data_len, u8 *mic)
|
||||
-{
|
||||
- size_t mic_len = crypto_aead_authsize(tfm);
|
||||
- struct scatterlist sg[3];
|
||||
- struct aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
- int err;
|
||||
-
|
||||
- if (data_len == 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- __aad = (u8 *)aead_req + reqsize;
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- sg_init_table(sg, 3);
|
||||
- sg_set_buf(&sg[0], __aad, aad_len);
|
||||
- sg_set_buf(&sg[1], data, data_len);
|
||||
- sg_set_buf(&sg[2], mic, mic_len);
|
||||
-
|
||||
- aead_request_set_tfm(aead_req, tfm);
|
||||
- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
|
||||
- aead_request_set_ad(aead_req, sg[0].length);
|
||||
-
|
||||
- err = crypto_aead_decrypt(aead_req);
|
||||
- kzfree(aead_req);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-struct crypto_aead *
|
||||
-aead_key_setup_encrypt(const char *alg, const u8 key[],
|
||||
- size_t key_len, size_t mic_len)
|
||||
-{
|
||||
- struct crypto_aead *tfm;
|
||||
- int err;
|
||||
-
|
||||
- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
|
||||
- if (IS_ERR(tfm))
|
||||
- return tfm;
|
||||
-
|
||||
- err = crypto_aead_setkey(tfm, key, key_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
- err = crypto_aead_setauthsize(tfm, mic_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
-
|
||||
- return tfm;
|
||||
-
|
||||
-free_aead:
|
||||
- crypto_free_aead(tfm);
|
||||
- return ERR_PTR(err);
|
||||
-}
|
||||
-
|
||||
-void aead_key_free(struct crypto_aead *tfm)
|
||||
-{
|
||||
- crypto_free_aead(tfm);
|
||||
-}
|
||||
--- a/net/mac80211/aead_api.h
|
||||
+++ /dev/null
|
||||
@@ -1,27 +0,0 @@
|
||||
-/*
|
||||
- * This program is free software; you can redistribute it and/or modify
|
||||
- * it under the terms of the GNU General Public License version 2 as
|
||||
- * published by the Free Software Foundation.
|
||||
- */
|
||||
-
|
||||
-#ifndef _AEAD_API_H
|
||||
-#define _AEAD_API_H
|
||||
-
|
||||
-#include <crypto/aead.h>
|
||||
-#include <linux/crypto.h>
|
||||
-
|
||||
-struct crypto_aead *
|
||||
-aead_key_setup_encrypt(const char *alg, const u8 key[],
|
||||
- size_t key_len, size_t mic_len);
|
||||
-
|
||||
-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
||||
- size_t aad_len, u8 *data,
|
||||
- size_t data_len, u8 *mic);
|
||||
-
|
||||
-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
||||
- size_t aad_len, u8 *data,
|
||||
- size_t data_len, u8 *mic);
|
||||
-
|
||||
-void aead_key_free(struct crypto_aead *tfm);
|
||||
-
|
||||
-#endif /* _AEAD_API_H */
|
||||
--- a/net/mac80211/aes_ccm.h
|
||||
+++ b/net/mac80211/aes_ccm.h
|
||||
@@ -10,39 +10,17 @@
|
||||
#ifndef AES_CCM_H
|
||||
#define AES_CCM_H
|
||||
|
||||
-#include "aead_api.h"
|
||||
+#include <linux/crypto.h>
|
||||
|
||||
-#define CCM_AAD_LEN 32
|
||||
-
|
||||
-static inline struct crypto_aead *
|
||||
-ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
|
||||
-{
|
||||
- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
|
||||
-}
|
||||
-
|
||||
-static inline int
|
||||
-ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
|
||||
- u8 *b_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
-{
|
||||
- return aead_encrypt(tfm, b_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
-}
|
||||
-
|
||||
-static inline int
|
||||
-ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
|
||||
- u8 *b_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
-{
|
||||
- return aead_decrypt(tfm, b_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
-}
|
||||
-
|
||||
-static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
|
||||
-{
|
||||
- return aead_key_free(tfm);
|
||||
-}
|
||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len,
|
||||
+ size_t mic_len);
|
||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len);
|
||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len);
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
|
||||
|
||||
#endif /* AES_CCM_H */
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/aes_gcm.c
|
||||
@@ -0,0 +1,109 @@
|
||||
+/*
|
||||
+ * Copyright 2014-2015, Qualcomm Atheros, Inc.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <crypto/aead.h>
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "key.h"
|
||||
+#include "aes_gcm.h"
|
||||
+
|
||||
+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ struct scatterlist sg[3];
|
||||
+ struct aead_request *aead_req;
|
||||
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
+ u8 *__aad;
|
||||
+
|
||||
+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
|
||||
+ if (!aead_req)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ __aad = (u8 *)aead_req + reqsize;
|
||||
+ memcpy(__aad, aad, GCM_AAD_LEN);
|
||||
+
|
||||
+ sg_init_table(sg, 3);
|
||||
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
||||
+ sg_set_buf(&sg[1], data, data_len);
|
||||
+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
|
||||
+
|
||||
+ aead_request_set_tfm(aead_req, tfm);
|
||||
+ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
|
||||
+ aead_request_set_ad(aead_req, sg[0].length);
|
||||
+
|
||||
+ crypto_aead_encrypt(aead_req);
|
||||
+ kzfree(aead_req);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ struct scatterlist sg[3];
|
||||
+ struct aead_request *aead_req;
|
||||
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
+ u8 *__aad;
|
||||
+ int err;
|
||||
+
|
||||
+ if (data_len == 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
|
||||
+ if (!aead_req)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ __aad = (u8 *)aead_req + reqsize;
|
||||
+ memcpy(__aad, aad, GCM_AAD_LEN);
|
||||
+
|
||||
+ sg_init_table(sg, 3);
|
||||
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
||||
+ sg_set_buf(&sg[1], data, data_len);
|
||||
+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
|
||||
+
|
||||
+ aead_request_set_tfm(aead_req, tfm);
|
||||
+ aead_request_set_crypt(aead_req, sg, sg,
|
||||
+ data_len + IEEE80211_GCMP_MIC_LEN, j_0);
|
||||
+ aead_request_set_ad(aead_req, sg[0].length);
|
||||
+
|
||||
+ err = crypto_aead_decrypt(aead_req);
|
||||
+ kzfree(aead_req);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len)
|
||||
+{
|
||||
+ struct crypto_aead *tfm;
|
||||
+ int err;
|
||||
+
|
||||
+ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
|
||||
+ if (IS_ERR(tfm))
|
||||
+ return tfm;
|
||||
+
|
||||
+ err = crypto_aead_setkey(tfm, key, key_len);
|
||||
+ if (err)
|
||||
+ goto free_aead;
|
||||
+ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
|
||||
+ if (err)
|
||||
+ goto free_aead;
|
||||
+
|
||||
+ return tfm;
|
||||
+
|
||||
+free_aead:
|
||||
+ crypto_free_aead(tfm);
|
||||
+ return ERR_PTR(err);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
+{
|
||||
+ crypto_free_aead(tfm);
|
||||
+}
|
||||
--- a/net/mac80211/aes_gcm.h
|
||||
+++ b/net/mac80211/aes_gcm.h
|
||||
@@ -9,38 +9,30 @@
|
||||
#ifndef AES_GCM_H
|
||||
#define AES_GCM_H
|
||||
|
||||
-#include "aead_api.h"
|
||||
+#include <linux/crypto.h>
|
||||
|
||||
-#define GCM_AAD_LEN 32
|
||||
-
|
||||
-static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
|
||||
- u8 *j_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
+static inline void
|
||||
+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- return aead_encrypt(tfm, j_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
}
|
||||
|
||||
-static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
|
||||
- u8 *j_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
+static inline int
|
||||
+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- return aead_decrypt(tfm, j_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
+ return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct crypto_aead *
|
||||
ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
|
||||
{
|
||||
- return aead_key_setup_encrypt("gcm(aes)", key,
|
||||
- key_len, IEEE80211_GCMP_MIC_LEN);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
-static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
+static inline void
|
||||
+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
{
|
||||
- return aead_key_free(tfm);
|
||||
}
|
||||
|
||||
#endif /* AES_GCM_H */
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -306,7 +306,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||
}
|
||||
|
||||
|
||||
-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
|
||||
+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
|
||||
+ u16 data_len)
|
||||
{
|
||||
__le16 mask_fc;
|
||||
int a4_included, mgmt;
|
||||
@@ -336,14 +337,8 @@ static void ccmp_special_blocks(struct s
|
||||
else
|
||||
qos_tid = 0;
|
||||
|
||||
- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
|
||||
- * mode authentication are not allowed to collide, yet both are derived
|
||||
- * from this vector b_0. We only set L := 1 here to indicate that the
|
||||
- * data size can be represented in (L+1) bytes. The CCM layer will take
|
||||
- * care of storing the data length in the top (L+1) bytes and setting
|
||||
- * and clearing the other bits as is required to derive the two IVs.
|
||||
- */
|
||||
- b_0[0] = 0x1;
|
||||
+ /* First block, b_0 */
|
||||
+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
|
||||
|
||||
/* Nonce: Nonce Flags | A2 | PN
|
||||
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
|
||||
@@ -351,6 +346,8 @@ static void ccmp_special_blocks(struct s
|
||||
b_0[1] = qos_tid | (mgmt << 4);
|
||||
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
|
||||
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
|
||||
+ /* l(m) */
|
||||
+ put_unaligned_be16(data_len, &b_0[14]);
|
||||
|
||||
/* AAD (extra authenticate-only data) / masked 802.11 header
|
||||
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
|
||||
@@ -407,7 +404,7 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
u64 pn64;
|
||||
- u8 aad[CCM_AAD_LEN];
|
||||
+ u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 b_0[AES_BLOCK_SIZE];
|
||||
|
||||
if (info->control.hw_key &&
|
||||
@@ -462,9 +459,11 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
return 0;
|
||||
|
||||
pos += IEEE80211_CCMP_HDR_LEN;
|
||||
- ccmp_special_blocks(skb, pn, b_0, aad);
|
||||
- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
|
||||
- skb_put(skb, mic_len));
|
||||
+ ccmp_special_blocks(skb, pn, b_0, aad, len);
|
||||
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
|
||||
+ skb_put(skb, mic_len), mic_len);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -537,13 +536,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 b_0[AES_BLOCK_SIZE];
|
||||
/* hardware didn't decrypt/verify MIC */
|
||||
- ccmp_special_blocks(skb, pn, b_0, aad);
|
||||
+ ccmp_special_blocks(skb, pn, b_0, aad, data_len);
|
||||
|
||||
if (ieee80211_aes_ccm_decrypt(
|
||||
key->u.ccmp.tfm, b_0, aad,
|
||||
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
|
||||
data_len,
|
||||
- skb->data + skb->len - mic_len))
|
||||
+ skb->data + skb->len - mic_len, mic_len))
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
@@ -639,7 +638,7 @@ static int gcmp_encrypt_skb(struct ieee8
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
u64 pn64;
|
||||
- u8 aad[GCM_AAD_LEN];
|
||||
+ u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 j_0[AES_BLOCK_SIZE];
|
||||
|
||||
if (info->control.hw_key &&
|
||||
@@ -696,8 +695,10 @@ static int gcmp_encrypt_skb(struct ieee8
|
||||
|
||||
pos += IEEE80211_GCMP_HDR_LEN;
|
||||
gcmp_special_blocks(skb, pn, j_0, aad);
|
||||
- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
|
||||
- skb_put(skb, IEEE80211_GCMP_MIC_LEN));
|
||||
+ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
|
||||
+ skb_put(skb, IEEE80211_GCMP_MIC_LEN));
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
ieee80211_tx_result
|
||||
@@ -1121,9 +1122,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
|
||||
struct ieee80211_key *key = tx->key;
|
||||
struct ieee80211_mmie_16 *mmie;
|
||||
struct ieee80211_hdr *hdr;
|
||||
- u8 aad[GMAC_AAD_LEN];
|
||||
+ u8 aad[20];
|
||||
u64 pn64;
|
||||
- u8 nonce[GMAC_NONCE_LEN];
|
||||
+ u8 nonce[12];
|
||||
|
||||
if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
|
||||
return TX_DROP;
|
||||
@@ -1169,7 +1170,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_key *key = rx->key;
|
||||
struct ieee80211_mmie_16 *mmie;
|
||||
- u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN];
|
||||
+ u8 aad[20], mic[16], ipn[6], nonce[12];
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
if (!ieee80211_is_mgmt(hdr->frame_control))
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/aes_ccm.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
+ * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
+ *
|
||||
+ * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <crypto/aead.h>
|
||||
+#include <crypto/aes.h>
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "key.h"
|
||||
+#include "aes_ccm.h"
|
||||
+
|
||||
+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
|
||||
+ u8 *a, u8 *b)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
+
|
||||
+ /* Extra Authenticate-only data (always two AES blocks) */
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ aad[i] ^= b[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, b, aad);
|
||||
+
|
||||
+ aad += AES_BLOCK_SIZE;
|
||||
+
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ aad[i] ^= b[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, a, aad);
|
||||
+
|
||||
+ /* Mask out bits from auth-only-b_0 */
|
||||
+ b_0[0] &= 0x07;
|
||||
+
|
||||
+ /* S_0 is used to encrypt T (= MIC) */
|
||||
+ b_0[14] = 0;
|
||||
+ b_0[15] = 0;
|
||||
+ crypto_cipher_encrypt_one(tfm, s_0, b_0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ int i, j, last_len, num_blocks;
|
||||
+ u8 b[AES_BLOCK_SIZE];
|
||||
+ u8 s_0[AES_BLOCK_SIZE];
|
||||
+ u8 e[AES_BLOCK_SIZE];
|
||||
+ u8 *pos, *cpos;
|
||||
+
|
||||
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
|
||||
+ last_len = data_len % AES_BLOCK_SIZE;
|
||||
+ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
|
||||
+
|
||||
+ /* Process payload blocks */
|
||||
+ pos = data;
|
||||
+ cpos = data;
|
||||
+ for (j = 1; j <= num_blocks; j++) {
|
||||
+ int blen = (j == num_blocks && last_len) ?
|
||||
+ last_len : AES_BLOCK_SIZE;
|
||||
+
|
||||
+ /* Authentication followed by encryption */
|
||||
+ for (i = 0; i < blen; i++)
|
||||
+ b[i] ^= pos[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b);
|
||||
+
|
||||
+ b_0[14] = (j >> 8) & 0xff;
|
||||
+ b_0[15] = j & 0xff;
|
||||
+ crypto_cipher_encrypt_one(tfm, e, b_0);
|
||||
+ for (i = 0; i < blen; i++)
|
||||
+ *cpos++ = *pos++ ^ e[i];
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mic_len; i++)
|
||||
+ mic[i] = b[i] ^ s_0[i];
|
||||
+}
|
||||
+
|
||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ int i, j, last_len, num_blocks;
|
||||
+ u8 *pos, *cpos;
|
||||
+ u8 a[AES_BLOCK_SIZE];
|
||||
+ u8 b[AES_BLOCK_SIZE];
|
||||
+ u8 s_0[AES_BLOCK_SIZE];
|
||||
+
|
||||
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
|
||||
+ last_len = data_len % AES_BLOCK_SIZE;
|
||||
+ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
|
||||
+
|
||||
+ /* Process payload blocks */
|
||||
+ cpos = data;
|
||||
+ pos = data;
|
||||
+ for (j = 1; j <= num_blocks; j++) {
|
||||
+ int blen = (j == num_blocks && last_len) ?
|
||||
+ last_len : AES_BLOCK_SIZE;
|
||||
+
|
||||
+ /* Decryption followed by authentication */
|
||||
+ b_0[14] = (j >> 8) & 0xff;
|
||||
+ b_0[15] = j & 0xff;
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
+ for (i = 0; i < blen; i++) {
|
||||
+ *pos = *cpos++ ^ b[i];
|
||||
+ a[i] ^= *pos++;
|
||||
+ }
|
||||
+ crypto_cipher_encrypt_one(tfm, a, a);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mic_len; i++) {
|
||||
+ if ((mic[i] ^ s_0[i]) != a[i])
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ struct crypto_cipher *tfm;
|
||||
+
|
||||
+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
+ if (!IS_ERR(tfm))
|
||||
+ crypto_cipher_setkey(tfm, key, key_len);
|
||||
+
|
||||
+ return tfm;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
|
||||
+{
|
||||
+ crypto_free_cipher(tfm);
|
||||
+}
|
||||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -5,8 +5,6 @@ config MAC80211
|
||||
depends on CRYPTO
|
||||
depends on CRYPTO_ARC4
|
||||
depends on CRYPTO_AES
|
||||
- depends on CRYPTO_CCM
|
||||
- depends on CRYPTO_GCM
|
||||
depends on CRYPTO_CMAC
|
||||
depends on CRC32
|
||||
---help---
|
||||
--- a/net/mac80211/aes_gmac.h
|
||||
+++ b/net/mac80211/aes_gmac.h
|
||||
@@ -15,10 +15,22 @@
|
||||
#define GMAC_MIC_LEN 16
|
||||
#define GMAC_NONCE_LEN 12
|
||||
|
||||
-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
|
||||
- size_t key_len);
|
||||
-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
- const u8 *data, size_t data_len, u8 *mic);
|
||||
-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
|
||||
+static inline struct crypto_aead *
|
||||
+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
+ const u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
|
||||
+{
|
||||
+}
|
||||
|
||||
#endif /* AES_GMAC_H */
|
||||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -88,7 +88,7 @@ struct ieee80211_key {
|
||||
* Management frames.
|
||||
*/
|
||||
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
|
||||
- struct crypto_aead *tfm;
|
||||
+ struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
||||
} ccmp;
|
||||
struct {
|
|
@ -0,0 +1,12 @@
|
|||
Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1058,7 +1058,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
- ieee80211_free_keys(sdata, true);
|
||||
|
||||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
sdata->vif.bss_conf.ssid_len = 0;
|
|
@ -0,0 +1,43 @@
|
|||
--- a/net/wireless/sysfs.c
|
||||
+++ b/net/wireless/sysfs.c
|
||||
@@ -24,18 +24,35 @@ static inline struct cfg80211_registered
|
||||
return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
|
||||
}
|
||||
|
||||
-#define SHOW_FMT(name, fmt, member) \
|
||||
+#define SHOW_FMT(name, fmt, member, mode) \
|
||||
static ssize_t name ## _show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
|
||||
} \
|
||||
-static DEVICE_ATTR_RO(name)
|
||||
+static DEVICE_ATTR_##mode(name)
|
||||
|
||||
-SHOW_FMT(index, "%d", wiphy_idx);
|
||||
-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
|
||||
-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
|
||||
+static ssize_t macaddress_store(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t len)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
|
||||
+
|
||||
+ return strnlen(buf, len);
|
||||
+}
|
||||
+
|
||||
+SHOW_FMT(index, "%d", wiphy_idx, RO);
|
||||
+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
|
||||
+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
|
||||
|
||||
static ssize_t name_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
32
root/package/kernel/mac80211/patches/130-disable-fils.patch
Normal file
32
root/package/kernel/mac80211/patches/130-disable-fils.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
Disable FILS support, since it pulls in crypto hash support
|
||||
|
||||
--- a/net/mac80211/fils_aead.h
|
||||
+++ b/net/mac80211/fils_aead.h
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef FILS_AEAD_H
|
||||
#define FILS_AEAD_H
|
||||
|
||||
-#if LINUX_VERSION_IS_GEQ(4,3,0)
|
||||
+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */
|
||||
int fils_encrypt_assoc_req(struct sk_buff *skb,
|
||||
struct ieee80211_mgd_assoc_data *assoc_data);
|
||||
int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/fils_aead.c
|
||||
+++ b/net/mac80211/fils_aead.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-#if LINUX_VERSION_IS_GEQ(4,3,0)
|
||||
+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */
|
||||
/*
|
||||
* FILS AEAD for (Re)Association Request/Response frames
|
||||
* Copyright 2016, Qualcomm Atheros, Inc.
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -550,7 +550,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
NL80211_FEATURE_MAC_ON_CREATE |
|
||||
NL80211_FEATURE_USERSPACE_MPM |
|
||||
NL80211_FEATURE_FULL_AP_CLIENT_STATE;
|
||||
-#if LINUX_VERSION_IS_GEQ(4,3,0)
|
||||
+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */
|
||||
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 7 Oct 2017 09:37:28 +0200
|
||||
Subject: [PATCH] Revert "mac80211: aes-cmac: switch to shash CMAC
|
||||
driver"
|
||||
|
||||
This reverts commit 26717828b75dd5c46e97f7f4a9b937d038bb2852.
|
||||
Reduces mac80211 dependencies for LEDE
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/aes_cmac.c
|
||||
+++ b/net/mac80211/aes_cmac.c
|
||||
@@ -22,50 +22,126 @@
|
||||
#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
|
||||
#define AAD_LEN 20
|
||||
|
||||
-static const u8 zero[CMAC_TLEN_256];
|
||||
|
||||
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
|
||||
- const u8 *data, size_t data_len, u8 *mic)
|
||||
+void gf_mulx(u8 *pad)
|
||||
+{
|
||||
+ int i, carry;
|
||||
+
|
||||
+ carry = pad[0] & 0x80;
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
|
||||
+ pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
|
||||
+ pad[AES_BLOCK_SIZE - 1] <<= 1;
|
||||
+ if (carry)
|
||||
+ pad[AES_BLOCK_SIZE - 1] ^= 0x87;
|
||||
+}
|
||||
+
|
||||
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
|
||||
+ const u8 *addr[], const size_t *len, u8 *mac,
|
||||
+ size_t mac_len)
|
||||
{
|
||||
- SHASH_DESC_ON_STACK(desc, tfm);
|
||||
- u8 out[AES_BLOCK_SIZE];
|
||||
+ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
|
||||
+ const u8 *pos, *end;
|
||||
+ size_t i, e, left, total_len;
|
||||
+
|
||||
+ memset(cbc, 0, AES_BLOCK_SIZE);
|
||||
+
|
||||
+ total_len = 0;
|
||||
+ for (e = 0; e < num_elem; e++)
|
||||
+ total_len += len[e];
|
||||
+ left = total_len;
|
||||
+
|
||||
+ e = 0;
|
||||
+ pos = addr[0];
|
||||
+ end = pos + len[0];
|
||||
+
|
||||
+ while (left >= AES_BLOCK_SIZE) {
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
+ cbc[i] ^= *pos++;
|
||||
+ if (pos >= end) {
|
||||
+ e++;
|
||||
+ pos = addr[e];
|
||||
+ end = pos + len[e];
|
||||
+ }
|
||||
+ }
|
||||
+ if (left > AES_BLOCK_SIZE)
|
||||
+ crypto_cipher_encrypt_one(tfm, cbc, cbc);
|
||||
+ left -= AES_BLOCK_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ memset(pad, 0, AES_BLOCK_SIZE);
|
||||
+ crypto_cipher_encrypt_one(tfm, pad, pad);
|
||||
+ gf_mulx(pad);
|
||||
+
|
||||
+ if (left || total_len == 0) {
|
||||
+ for (i = 0; i < left; i++) {
|
||||
+ cbc[i] ^= *pos++;
|
||||
+ if (pos >= end) {
|
||||
+ e++;
|
||||
+ pos = addr[e];
|
||||
+ end = pos + len[e];
|
||||
+ }
|
||||
+ }
|
||||
+ cbc[left] ^= 0x80;
|
||||
+ gf_mulx(pad);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ pad[i] ^= cbc[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, pad, pad);
|
||||
+ memcpy(mac, pad, mac_len);
|
||||
+}
|
||||
|
||||
- desc->tfm = tfm;
|
||||
|
||||
- crypto_shash_init(desc);
|
||||
- crypto_shash_update(desc, aad, AAD_LEN);
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN);
|
||||
- crypto_shash_finup(desc, zero, CMAC_TLEN, out);
|
||||
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
|
||||
+ const u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ const u8 *addr[3];
|
||||
+ size_t len[3];
|
||||
+ u8 zero[CMAC_TLEN];
|
||||
+
|
||||
+ memset(zero, 0, CMAC_TLEN);
|
||||
+ addr[0] = aad;
|
||||
+ len[0] = AAD_LEN;
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN;
|
||||
|
||||
- memcpy(mic, out, CMAC_TLEN);
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN);
|
||||
}
|
||||
|
||||
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
|
||||
+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
|
||||
const u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- SHASH_DESC_ON_STACK(desc, tfm);
|
||||
+ const u8 *addr[3];
|
||||
+ size_t len[3];
|
||||
+ u8 zero[CMAC_TLEN_256];
|
||||
+
|
||||
+ memset(zero, 0, CMAC_TLEN_256);
|
||||
+ addr[0] = aad;
|
||||
+ len[0] = AAD_LEN;
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN_256;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN_256;
|
||||
|
||||
- desc->tfm = tfm;
|
||||
-
|
||||
- crypto_shash_init(desc);
|
||||
- crypto_shash_update(desc, aad, AAD_LEN);
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
|
||||
- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256);
|
||||
}
|
||||
|
||||
-struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
|
||||
- size_t key_len)
|
||||
+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
|
||||
+ size_t key_len)
|
||||
{
|
||||
- struct crypto_shash *tfm;
|
||||
+ struct crypto_cipher *tfm;
|
||||
|
||||
- tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
|
||||
+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
if (!IS_ERR(tfm))
|
||||
- crypto_shash_setkey(tfm, key, key_len);
|
||||
+ crypto_cipher_setkey(tfm, key, key_len);
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
-void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm)
|
||||
+
|
||||
+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
|
||||
{
|
||||
- crypto_free_shash(tfm);
|
||||
+ crypto_free_cipher(tfm);
|
||||
}
|
||||
--- a/net/mac80211/aes_cmac.h
|
||||
+++ b/net/mac80211/aes_cmac.h
|
||||
@@ -10,14 +10,13 @@
|
||||
#define AES_CMAC_H
|
||||
|
||||
#include <linux/crypto.h>
|
||||
-#include <crypto/hash.h>
|
||||
|
||||
-struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
|
||||
- size_t key_len);
|
||||
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
|
||||
+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
|
||||
+ size_t key_len);
|
||||
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
|
||||
const u8 *data, size_t data_len, u8 *mic);
|
||||
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
|
||||
+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad,
|
||||
const u8 *data, size_t data_len, u8 *mic);
|
||||
-void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm);
|
||||
+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
|
||||
|
||||
#endif /* AES_CMAC_H */
|
||||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -93,7 +93,7 @@ struct ieee80211_key {
|
||||
} ccmp;
|
||||
struct {
|
||||
u8 rx_pn[IEEE80211_CMAC_PN_LEN];
|
||||
- struct crypto_shash *tfm;
|
||||
+ struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCMACReplays */
|
||||
u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
|
||||
} aes_cmac;
|
|
@ -0,0 +1,10 @@
|
|||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -5,7 +5,6 @@ config MAC80211
|
||||
depends on CRYPTO
|
||||
depends on CRYPTO_ARC4
|
||||
depends on CRYPTO_AES
|
||||
- depends on CRYPTO_CMAC
|
||||
depends on CRC32
|
||||
---help---
|
||||
This option enables the hardware independent IEEE 802.11
|
|
@ -0,0 +1,15 @@
|
|||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3750,6 +3750,12 @@ out:
|
||||
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
+#if defined(sk_pacing_shift) || LINUX_VERSION_IS_GEQ(4,15,0)
|
||||
+ if (skb->sk && sk_fullsock(skb->sk) &&
|
||||
+ skb->sk->sk_pacing_shift != 6)
|
||||
+ skb->sk->sk_pacing_shift = 6;
|
||||
+#endif
|
||||
+
|
||||
if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) {
|
||||
struct sk_buff_head queue;
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -292,7 +292,7 @@ void ieee80211_restart_hw(struct ieee802
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
static int ieee80211_ifa_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -351,7 +351,7 @@ static int ieee80211_ifa_changed(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -1114,14 +1114,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
if (result)
|
||||
goto fail_flows;
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
|
||||
result = register_inetaddr_notifier(&local->ifa_notifier);
|
||||
if (result)
|
||||
goto fail_ifa;
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1130,13 +1130,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
fail_ifa6:
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
#endif
|
||||
-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
|
||||
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
|
||||
fail_ifa:
|
||||
#endif
|
||||
ieee80211_txq_teardown_flows(local);
|
||||
@@ -1166,10 +1166,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
tasklet_kill(&local->tx_pending_tasklet);
|
||||
tasklet_kill(&local->tasklet);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
unregister_inet6addr_notifier(&local->ifa6_notifier);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
From: Thomas Hebb <tommyhebb@gmail.com>
|
||||
Subject: [PATCH] ath10k: search all IEs for variant before falling back
|
||||
Date: Wed, 21 Feb 2018 11:43:39 -0500
|
||||
|
||||
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
|
||||
extension") added a feature to ath10k that allows Board Data File
|
||||
(BDF) conflicts between multiple devices that use the same device IDs
|
||||
but have different calibration requirements to be resolved by allowing
|
||||
a "variant" string to be stored in SMBIOS [and later device tree, added
|
||||
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
|
||||
variant")] that gets appended to the ID stored in board-2.bin.
|
||||
|
||||
This original patch had a regression, however. Namely that devices with
|
||||
a variant present in SMBIOS that didn't need custom BDFs could no longer
|
||||
find the default BDF, which has no variant appended. The patch was
|
||||
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
|
||||
("search SMBIOS for OEM board file extension").
|
||||
|
||||
But the fix to fall back to a default BDF introduced another issue: the
|
||||
driver currently parses IEs in board-2.bin one by one, and for each one
|
||||
it first checks to see if it matches the ID with the variant appended.
|
||||
If it doesn't, it checks to see if it matches the "fallback" ID with no
|
||||
variant. If a matching BDF is found at any point during this search, the
|
||||
search is terminated and that BDF is used. The issue is that it's very
|
||||
possible (and is currently the case for board-2.bin files present in the
|
||||
ath10k-firmware repository) for the default BDF to occur in an earlier
|
||||
IE than the variant-specific BDF. In this case, the current code will
|
||||
happily choose the default BDF even though a better-matching BDF is
|
||||
present later in the file.
|
||||
|
||||
This patch fixes the issue by first searching the entire file for the ID
|
||||
with variant, and searching for the fallback ID only if that search
|
||||
fails. It also includes some code cleanup in the area, as
|
||||
ath10k_core_fetch_board_data_api_n() no longer does its own string
|
||||
mangling to remove the variant from an ID, instead leaving that job to a
|
||||
new flag passed to ath10k_core_create_board_name().
|
||||
|
||||
I've tested this patch on a QCA4019 and verified that the driver behaves
|
||||
correctly for 1) both fallback and variant BDFs present, 2) only fallback
|
||||
BDF present, and 3) no matching BDFs present.
|
||||
|
||||
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
|
||||
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.c | 134 ++++++++++++++++++---------------
|
||||
1 file changed, 72 insertions(+), 62 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -1132,14 +1132,61 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ath10k_core_search_bd(struct ath10k *ar,
|
||||
+ const char *boardname,
|
||||
+ const u8 *data,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ size_t ie_len;
|
||||
+ struct ath10k_fw_ie *hdr;
|
||||
+ int ret = -ENOENT, ie_id;
|
||||
+
|
||||
+ while (len > sizeof(struct ath10k_fw_ie)) {
|
||||
+ hdr = (struct ath10k_fw_ie *)data;
|
||||
+ ie_id = le32_to_cpu(hdr->id);
|
||||
+ ie_len = le32_to_cpu(hdr->len);
|
||||
+
|
||||
+ len -= sizeof(*hdr);
|
||||
+ data = hdr->data;
|
||||
+
|
||||
+ if (len < ALIGN(ie_len, 4)) {
|
||||
+ ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
|
||||
+ ie_id, ie_len, len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (ie_id) {
|
||||
+ case ATH10K_BD_IE_BOARD:
|
||||
+ ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
||||
+ boardname);
|
||||
+ if (ret == -ENOENT)
|
||||
+ /* no match found, continue */
|
||||
+ break;
|
||||
+
|
||||
+ /* either found or error, so stop searching */
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* jump over the padding */
|
||||
+ ie_len = ALIGN(ie_len, 4);
|
||||
+
|
||||
+ len -= ie_len;
|
||||
+ data += ie_len;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ /* return result of parse_bd_ie_board() or -ENOENT */
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
|
||||
const char *boardname,
|
||||
+ const char *fallback_boardname,
|
||||
const char *filename)
|
||||
{
|
||||
- size_t len, magic_len, ie_len;
|
||||
- struct ath10k_fw_ie *hdr;
|
||||
+ size_t len, magic_len;
|
||||
const u8 *data;
|
||||
- int ret, ie_id;
|
||||
+ int ret;
|
||||
|
||||
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
||||
ar->hw_params.fw.dir,
|
||||
@@ -1177,69 +1224,23 @@ static int ath10k_core_fetch_board_data_
|
||||
data += magic_len;
|
||||
len -= magic_len;
|
||||
|
||||
- while (len > sizeof(struct ath10k_fw_ie)) {
|
||||
- hdr = (struct ath10k_fw_ie *)data;
|
||||
- ie_id = le32_to_cpu(hdr->id);
|
||||
- ie_len = le32_to_cpu(hdr->len);
|
||||
-
|
||||
- len -= sizeof(*hdr);
|
||||
- data = hdr->data;
|
||||
-
|
||||
- if (len < ALIGN(ie_len, 4)) {
|
||||
- ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
|
||||
- ie_id, ie_len, len);
|
||||
- ret = -EINVAL;
|
||||
- goto err;
|
||||
- }
|
||||
+ /* attempt to find boardname in the IE list */
|
||||
+ ret = ath10k_core_search_bd(ar, boardname, data, len);
|
||||
|
||||
- switch (ie_id) {
|
||||
- case ATH10K_BD_IE_BOARD:
|
||||
- ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
||||
- boardname);
|
||||
- if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') {
|
||||
- /* try default bdf if variant was not found */
|
||||
- char *s, *v = ",variant=";
|
||||
- char boardname2[100];
|
||||
-
|
||||
- strlcpy(boardname2, boardname,
|
||||
- sizeof(boardname2));
|
||||
-
|
||||
- s = strstr(boardname2, v);
|
||||
- if (s)
|
||||
- *s = '\0'; /* strip ",variant=%s" */
|
||||
-
|
||||
- ret = ath10k_core_parse_bd_ie_board(ar, data,
|
||||
- ie_len,
|
||||
- boardname2);
|
||||
- }
|
||||
+ /* if we didn't find it and have a fallback name, try that */
|
||||
+ if (ret == -ENOENT && fallback_boardname)
|
||||
+ ret = ath10k_core_search_bd(ar, fallback_boardname, data, len);
|
||||
|
||||
- if (ret == -ENOENT)
|
||||
- /* no match found, continue */
|
||||
- break;
|
||||
- else if (ret)
|
||||
- /* there was an error, bail out */
|
||||
- goto err;
|
||||
-
|
||||
- /* board data found */
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- /* jump over the padding */
|
||||
- ie_len = ALIGN(ie_len, 4);
|
||||
-
|
||||
- len -= ie_len;
|
||||
- data += ie_len;
|
||||
- }
|
||||
-
|
||||
-out:
|
||||
- if (!ar->normal_mode_fw.board_data || !ar->normal_mode_fw.board_len) {
|
||||
+ if (ret == -ENOENT) {
|
||||
ath10k_err(ar,
|
||||
"failed to fetch board data for %s from %s/%s\n",
|
||||
boardname, ar->hw_params.fw.dir, filename);
|
||||
ret = -ENODATA;
|
||||
- goto err;
|
||||
}
|
||||
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@@ -1248,12 +1249,12 @@ err:
|
||||
}
|
||||
|
||||
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
|
||||
- size_t name_len)
|
||||
+ size_t name_len, bool with_variant)
|
||||
{
|
||||
/* strlen(',variant=') + strlen(ar->id.bdf_ext) */
|
||||
char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
|
||||
|
||||
- if (ar->id.bdf_ext[0] != '\0')
|
||||
+ if (with_variant && ar->id.bdf_ext[0] != '\0')
|
||||
scnprintf(variant, sizeof(variant), ",variant=%s",
|
||||
ar->id.bdf_ext);
|
||||
|
||||
@@ -1279,17 +1280,26 @@ out:
|
||||
|
||||
static int ath10k_core_fetch_board_file(struct ath10k *ar)
|
||||
{
|
||||
- char boardname[100];
|
||||
+ char boardname[100], fallback_boardname[100];
|
||||
int ret;
|
||||
|
||||
- ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname));
|
||||
+ ret = ath10k_core_create_board_name(ar, boardname,
|
||||
+ sizeof(boardname), true);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to create board name: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = ath10k_core_create_board_name(ar, fallback_boardname,
|
||||
+ sizeof(boardname), false);
|
||||
+ if (ret) {
|
||||
+ ath10k_err(ar, "failed to create fallback board name: %d", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ar->bd_api = 2;
|
||||
ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
|
||||
+ fallback_boardname,
|
||||
ATH10K_BOARD_API2_FILE);
|
||||
if (!ret)
|
||||
goto success;
|
|
@ -0,0 +1,38 @@
|
|||
--- a/drivers/net/wireless/ath/ath5k/initvals.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
|
||||
@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini
|
||||
{ AR5K_IMR, 0 },
|
||||
{ AR5K_IER, AR5K_IER_DISABLE },
|
||||
{ AR5K_BSR, 0, AR5K_INI_READ },
|
||||
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
|
||||
{ AR5K_TXCFG, AR5K_DMASIZE_128B },
|
||||
{ AR5K_RXCFG, AR5K_DMASIZE_128B },
|
||||
+#else
|
||||
+ /* WAR for AR71xx PCI bug */
|
||||
+ { AR5K_TXCFG, AR5K_DMASIZE_128B },
|
||||
+ { AR5K_RXCFG, AR5K_DMASIZE_4B },
|
||||
+#endif
|
||||
{ AR5K_CFG, AR5K_INIT_CFG },
|
||||
{ AR5K_TOPS, 8 },
|
||||
{ AR5K_RXNOFRM, 8 },
|
||||
--- a/drivers/net/wireless/ath/ath5k/dma.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/dma.c
|
||||
@@ -869,10 +869,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah)
|
||||
* guess we can tweak it and see how it goes ;-)
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
|
||||
AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
|
||||
AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
|
||||
+#else
|
||||
+ /* WAR for AR71xx PCI bug */
|
||||
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
|
||||
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
|
||||
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
|
||||
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B);
|
||||
+#endif
|
||||
}
|
||||
|
||||
/* Pre-enable interrupts on 5211/5212*/
|
11
root/package/kernel/mac80211/patches/210-ap_scan.patch
Normal file
11
root/package/kernel/mac80211/patches/210-ap_scan.patch
Normal file
|
@ -0,0 +1,11 @@
|
|||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2215,7 +2215,7 @@ static int ieee80211_scan(struct wiphy *
|
||||
* the frames sent while scanning on other channel will be
|
||||
* lost)
|
||||
*/
|
||||
- if (sdata->u.ap.beacon &&
|
||||
+ if (0 && sdata->u.ap.beacon &&
|
||||
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
|
||||
!(req->flags & NL80211_SCAN_FLAG_AP)))
|
||||
return -EOPNOTSUPP;
|
|
@ -0,0 +1,72 @@
|
|||
From: Brian Norris <briannorris@chromium.org>
|
||||
Date: Thu, 19 Oct 2017 11:45:19 -0700
|
||||
Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM
|
||||
|
||||
Build errors have been reported with CONFIG_PM=n:
|
||||
|
||||
drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit
|
||||
declaration of function 'ath10k_pci_suspend'
|
||||
[-Werror=implicit-function-declaration]
|
||||
|
||||
drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit
|
||||
declaration of function 'ath10k_pci_resume'
|
||||
[-Werror=implicit-function-declaration]
|
||||
|
||||
These are caused by the combination of the following two commits:
|
||||
|
||||
6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused")
|
||||
96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but
|
||||
disabled")
|
||||
|
||||
Both build fine on their own.
|
||||
|
||||
But now that ath10k_pci_pm_{suspend,resume}() is compiled
|
||||
unconditionally, we should also compile ath10k_pci_{suspend,resume}()
|
||||
unconditionally.
|
||||
|
||||
And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they
|
||||
are trivial (empty), so we're not saving much space by compiling them
|
||||
out. And the alternatives would be to sprinkle more __maybe_unused, or
|
||||
spread the #ifdef's further.
|
||||
|
||||
Build tested with the following combinations:
|
||||
CONFIG_PM=y && CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM=y && CONFIG_PM_SLEEP=n
|
||||
CONFIG_PM=n
|
||||
|
||||
Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled")
|
||||
Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'")
|
||||
Signed-off-by: Brian Norris <briannorris@chromium.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/pci.c
|
||||
@@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at
|
||||
*/
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PM
|
||||
-
|
||||
static int ath10k_pci_hif_suspend(struct ath10k *ar)
|
||||
{
|
||||
/* Nothing to do; the important stuff is in the driver suspend. */
|
||||
@@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1
|
||||
|
||||
return ret;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static bool ath10k_pci_validate_cal(void *data, size_t size)
|
||||
{
|
||||
@@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10
|
||||
.power_down = ath10k_pci_hif_power_down,
|
||||
.read32 = ath10k_pci_read32,
|
||||
.write32 = ath10k_pci_write32,
|
||||
-#ifdef CONFIG_PM
|
||||
.suspend = ath10k_pci_hif_suspend,
|
||||
.resume = ath10k_pci_hif_resume,
|
||||
-#endif
|
||||
.fetch_cal_eeprom = ath10k_pci_hif_fetch_cal_eeprom,
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Mon, 20 Nov 2017 17:01:44 +0100
|
||||
Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg
|
||||
sessions
|
||||
|
||||
When deleting a station or otherwise tearing down all aggregation
|
||||
sessions, make sure to delete requested but not yet started ones,
|
||||
to avoid the following scenario:
|
||||
|
||||
* session is requested, added to tid_start_tx[]
|
||||
* ieee80211_ba_session_work() runs, gets past BLOCK_BA check
|
||||
* ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx,
|
||||
e.g. while deleting the station - deleting all active sessions
|
||||
* ieee80211_ba_session_work() continues since tear down flushes it, and
|
||||
calls ieee80211_tx_ba_session_handle_start() for the new session, arms
|
||||
the timer for it
|
||||
* station deletion continues to __cleanup_single_sta() and frees the
|
||||
session struct, while the timer is armed
|
||||
|
||||
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/agg-tx.c
|
||||
+++ b/net/mac80211/agg-tx.c
|
||||
@@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru
|
||||
|
||||
spin_lock_bh(&sta->lock);
|
||||
|
||||
+ /* free struct pending for start, if present */
|
||||
+ tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
|
||||
+ kfree(tid_tx);
|
||||
+ sta->ampdu_mlme.tid_start_tx[tid] = NULL;
|
||||
+
|
||||
tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
|
||||
if (!tid_tx) {
|
||||
spin_unlock_bh(&sta->lock);
|
|
@ -0,0 +1,25 @@
|
|||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Thu, 4 Jan 2018 15:51:53 +0100
|
||||
Subject: [PATCH] mac80211: mesh: drop frames appearing to be from us
|
||||
|
||||
If there are multiple mesh stations with the same MAC address,
|
||||
they will both get confused and start throwing warnings.
|
||||
|
||||
Obviously in this case nothing can actually work anyway, so just
|
||||
drop frames that look like they're from ourselves early on.
|
||||
|
||||
Reported-by: Gui Iribarren <gui@altermundi.net>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struc
|
||||
}
|
||||
return true;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
+ if (ether_addr_equal(sdata->vif.addr, hdr->addr2))
|
||||
+ return false;
|
||||
if (multicast)
|
||||
return true;
|
||||
return ether_addr_equal(sdata->vif.addr, hdr->addr1);
|
|
@ -0,0 +1,60 @@
|
|||
From 2fd3877b5bb7d39782c3205a1dcda02023b8514a Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:31 +0100
|
||||
Subject: [PATCH] brcmfmac: handle FWHALT mailbox indication
|
||||
|
||||
The firmware uses a mailbox to communicate to the host what is going
|
||||
on. In the driver we validate the bit received. Various people seen
|
||||
the following message:
|
||||
|
||||
brcmfmac: brcmf_sdio_hostmail: Unknown mailbox data content: 0x40012
|
||||
|
||||
Bit 4 is cause of this message, but this actually indicates the firmware
|
||||
has halted. Handle this bit by giving a more meaningful error message.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -260,10 +260,11 @@ struct rte_console {
|
||||
#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */
|
||||
|
||||
/* tohostmailboxdata */
|
||||
-#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */
|
||||
-#define HMB_DATA_DEVREADY 2 /* talk to host after enable */
|
||||
-#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */
|
||||
-#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */
|
||||
+#define HMB_DATA_NAKHANDLED 0x0001 /* retransmit NAK'd frame */
|
||||
+#define HMB_DATA_DEVREADY 0x0002 /* talk to host after enable */
|
||||
+#define HMB_DATA_FC 0x0004 /* per prio flowcontrol update flag */
|
||||
+#define HMB_DATA_FWREADY 0x0008 /* fw ready for protocol activity */
|
||||
+#define HMB_DATA_FWHALT 0x0010 /* firmware halted */
|
||||
|
||||
#define HMB_DATA_FCDATA_MASK 0xff000000
|
||||
#define HMB_DATA_FCDATA_SHIFT 24
|
||||
@@ -1094,6 +1095,10 @@ static u32 brcmf_sdio_hostmail(struct br
|
||||
offsetof(struct sdpcmd_regs, tosbmailbox));
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
|
||||
+ /* dongle indicates the firmware has halted/crashed */
|
||||
+ if (hmb_data & HMB_DATA_FWHALT)
|
||||
+ brcmf_err("mailbox indicates firmware halted\n");
|
||||
+
|
||||
/* Dongle recomposed rx frames, accept them again */
|
||||
if (hmb_data & HMB_DATA_NAKHANDLED) {
|
||||
brcmf_dbg(SDIO, "Dongle reports NAK handled, expect rtx of %d\n",
|
||||
@@ -1151,6 +1156,7 @@ static u32 brcmf_sdio_hostmail(struct br
|
||||
HMB_DATA_NAKHANDLED |
|
||||
HMB_DATA_FC |
|
||||
HMB_DATA_FWREADY |
|
||||
+ HMB_DATA_FWHALT |
|
||||
HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
|
||||
brcmf_err("Unknown mailbox data content: 0x%02x\n",
|
||||
hmb_data);
|
|
@ -0,0 +1,133 @@
|
|||
From 6c219b0088158da839a5be63c5b3d96c145501d2 Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:32 +0100
|
||||
Subject: [PATCH] brcmfmac: disable packet filtering in promiscuous mode
|
||||
|
||||
Disable arp and nd offload to allow all packets sending to host.
|
||||
|
||||
Reported-by: Phil Elwell <phil@raspberrypi.org>
|
||||
Tested-by: Phil Elwell <phil@raspberrypi.org>
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 41 ----------------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 38 ++++++++++++++++++++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 1 +
|
||||
3 files changed, 39 insertions(+), 41 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -472,47 +472,6 @@ send_key_to_dongle(struct brcmf_if *ifp,
|
||||
return err;
|
||||
}
|
||||
|
||||
-static s32
|
||||
-brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
|
||||
-{
|
||||
- s32 err;
|
||||
- u32 mode;
|
||||
-
|
||||
- if (enable)
|
||||
- mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
|
||||
- else
|
||||
- mode = 0;
|
||||
-
|
||||
- /* Try to set and enable ARP offload feature, this may fail, then it */
|
||||
- /* is simply not supported and err 0 will be returned */
|
||||
- err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
|
||||
- if (err) {
|
||||
- brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
|
||||
- mode, err);
|
||||
- err = 0;
|
||||
- } else {
|
||||
- err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
|
||||
- if (err) {
|
||||
- brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
|
||||
- enable, err);
|
||||
- err = 0;
|
||||
- } else
|
||||
- brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
|
||||
- enable, mode);
|
||||
- }
|
||||
-
|
||||
- err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
|
||||
- if (err) {
|
||||
- brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
|
||||
- enable, err);
|
||||
- err = 0;
|
||||
- } else
|
||||
- brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
|
||||
- enable, mode);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static void
|
||||
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
|
||||
{
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct br
|
||||
return ifp;
|
||||
}
|
||||
|
||||
+void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
|
||||
+{
|
||||
+ s32 err;
|
||||
+ u32 mode;
|
||||
+
|
||||
+ if (enable)
|
||||
+ mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
|
||||
+ else
|
||||
+ mode = 0;
|
||||
+
|
||||
+ /* Try to set and enable ARP offload feature, this may fail, then it */
|
||||
+ /* is simply not supported and err 0 will be returned */
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
|
||||
+ if (err) {
|
||||
+ brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
|
||||
+ mode, err);
|
||||
+ } else {
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
|
||||
+ if (err) {
|
||||
+ brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
|
||||
+ enable, err);
|
||||
+ } else {
|
||||
+ brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
|
||||
+ enable, mode);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
|
||||
+ if (err) {
|
||||
+ brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
|
||||
+ enable, err);
|
||||
+ } else {
|
||||
+ brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
|
||||
+ enable, mode);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void _brcmf_set_multicast_list(struct work_struct *work)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
@@ -134,6 +171,7 @@ static void _brcmf_set_multicast_list(st
|
||||
if (err < 0)
|
||||
brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
|
||||
err);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, !cmd_value);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -203,6 +203,7 @@ int brcmf_netdev_wait_pend8021x(struct b
|
||||
/* Return pointer to interface name */
|
||||
char *brcmf_ifname(struct brcmf_if *ifp);
|
||||
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
|
||||
+void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable);
|
||||
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, const char *name, u8 *mac_addr);
|
|
@ -0,0 +1,133 @@
|
|||
From 8c6efda22f5f9f73fc948f517424466be01ae84d Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:33 +0100
|
||||
Subject: [PATCH] brcmfmac: cleanup brcmf_cfg80211_escan() function
|
||||
|
||||
The function brcmf_cfg80211_escan() was always called with a non-null
|
||||
request parameter and null pointer for this_ssid parameter. Clean up
|
||||
the function removing the dead code path.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 76 ++++------------------
|
||||
1 file changed, 11 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1072,18 +1072,10 @@ brcmf_do_escan(struct brcmf_if *ifp, str
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
|
||||
- struct cfg80211_scan_request *request,
|
||||
- struct cfg80211_ssid *this_ssid)
|
||||
+ struct cfg80211_scan_request *request)
|
||||
{
|
||||
- struct brcmf_if *ifp = vif->ifp;
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
- struct cfg80211_ssid *ssids;
|
||||
- u32 passive_scan;
|
||||
- bool escan_req;
|
||||
- bool spec_scan;
|
||||
s32 err;
|
||||
- struct brcmf_ssid_le ssid_le;
|
||||
- u32 SSID_len;
|
||||
|
||||
brcmf_dbg(SCAN, "START ESCAN\n");
|
||||
|
||||
@@ -1101,8 +1093,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
cfg->scan_status);
|
||||
return -EAGAIN;
|
||||
}
|
||||
- if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
|
||||
- brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
|
||||
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
|
||||
+ brcmf_err("Connecting: status (%lu)\n", vif->sme_state);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
@@ -1110,63 +1102,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
|
||||
vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
|
||||
|
||||
- escan_req = false;
|
||||
- if (request) {
|
||||
- /* scan bss */
|
||||
- ssids = request->ssids;
|
||||
- escan_req = true;
|
||||
- } else {
|
||||
- /* scan in ibss */
|
||||
- /* we don't do escan in ibss */
|
||||
- ssids = this_ssid;
|
||||
- }
|
||||
-
|
||||
cfg->scan_request = request;
|
||||
set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
||||
- if (escan_req) {
|
||||
- cfg->escan_info.run = brcmf_run_escan;
|
||||
- err = brcmf_p2p_scan_prep(wiphy, request, vif);
|
||||
- if (err)
|
||||
- goto scan_out;
|
||||
-
|
||||
- err = brcmf_do_escan(vif->ifp, request);
|
||||
- if (err)
|
||||
- goto scan_out;
|
||||
- } else {
|
||||
- brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
|
||||
- ssids->ssid, ssids->ssid_len);
|
||||
- memset(&ssid_le, 0, sizeof(ssid_le));
|
||||
- SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len);
|
||||
- ssid_le.SSID_len = cpu_to_le32(0);
|
||||
- spec_scan = false;
|
||||
- if (SSID_len) {
|
||||
- memcpy(ssid_le.SSID, ssids->ssid, SSID_len);
|
||||
- ssid_le.SSID_len = cpu_to_le32(SSID_len);
|
||||
- spec_scan = true;
|
||||
- } else
|
||||
- brcmf_dbg(SCAN, "Broadcast scan\n");
|
||||
-
|
||||
- passive_scan = cfg->active_scan ? 0 : 1;
|
||||
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
|
||||
- passive_scan);
|
||||
- if (err) {
|
||||
- brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
|
||||
- goto scan_out;
|
||||
- }
|
||||
- brcmf_scan_config_mpc(ifp, 0);
|
||||
- err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le,
|
||||
- sizeof(ssid_le));
|
||||
- if (err) {
|
||||
- if (err == -EBUSY)
|
||||
- brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
|
||||
- ssid_le.SSID);
|
||||
- else
|
||||
- brcmf_err("WLC_SCAN error (%d)\n", err);
|
||||
-
|
||||
- brcmf_scan_config_mpc(ifp, 1);
|
||||
- goto scan_out;
|
||||
- }
|
||||
- }
|
||||
+
|
||||
+ cfg->escan_info.run = brcmf_run_escan;
|
||||
+ err = brcmf_p2p_scan_prep(wiphy, request, vif);
|
||||
+ if (err)
|
||||
+ goto scan_out;
|
||||
+
|
||||
+ err = brcmf_do_escan(vif->ifp, request);
|
||||
+ if (err)
|
||||
+ goto scan_out;
|
||||
|
||||
/* Arm scan timeout timer */
|
||||
mod_timer(&cfg->escan_timeout, jiffies +
|
||||
@@ -1191,7 +1137,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
|
||||
if (!check_vif_up(vif))
|
||||
return -EIO;
|
||||
|
||||
- err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
|
||||
+ err = brcmf_cfg80211_escan(wiphy, vif, request);
|
||||
|
||||
if (err)
|
||||
brcmf_err("scan error (%d)\n", err);
|
|
@ -0,0 +1,31 @@
|
|||
From df2d8388bc96c0f29d27d121f2a4cd054f8b3900 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:34 +0100
|
||||
Subject: [PATCH] brcmfmac: use msecs_to_jiffies() instead of calculation using
|
||||
HZ
|
||||
|
||||
Minor cleanup using provided macro to convert milliseconds interval
|
||||
to jiffies in brcmf_cfg80211_escan().
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1115,8 +1115,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
goto scan_out;
|
||||
|
||||
/* Arm scan timeout timer */
|
||||
- mod_timer(&cfg->escan_timeout, jiffies +
|
||||
- BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
|
||||
+ mod_timer(&cfg->escan_timeout,
|
||||
+ jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
|
||||
|
||||
return 0;
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
From 588378f15cff285ac81c929239ccba01d7f71d50 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:35 +0100
|
||||
Subject: [PATCH] brcmfmac: get rid of brcmf_cfg80211_escan() function
|
||||
|
||||
The function brcmf_cfg80211_escan() is only called by brcmf_cfg80211_scan()
|
||||
so there is no reason to split in two function especially since the latter
|
||||
does not do an awful lot.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 34 +++++++---------------
|
||||
1 file changed, 10 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1071,13 +1071,16 @@ brcmf_do_escan(struct brcmf_if *ifp, str
|
||||
}
|
||||
|
||||
static s32
|
||||
-brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
|
||||
- struct cfg80211_scan_request *request)
|
||||
+brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
- s32 err;
|
||||
+ struct brcmf_cfg80211_vif *vif;
|
||||
+ s32 err = 0;
|
||||
|
||||
- brcmf_dbg(SCAN, "START ESCAN\n");
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+ vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
|
||||
+ if (!check_vif_up(vif))
|
||||
+ return -EIO;
|
||||
|
||||
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||
brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
|
||||
@@ -1102,6 +1105,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
|
||||
vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
|
||||
|
||||
+ brcmf_dbg(SCAN, "START ESCAN\n");
|
||||
+
|
||||
cfg->scan_request = request;
|
||||
set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
||||
|
||||
@@ -1121,31 +1126,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
return 0;
|
||||
|
||||
scan_out:
|
||||
+ brcmf_err("scan error (%d)\n", err);
|
||||
clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
|
||||
cfg->scan_request = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
-static s32
|
||||
-brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
|
||||
-{
|
||||
- struct brcmf_cfg80211_vif *vif;
|
||||
- s32 err = 0;
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Enter\n");
|
||||
- vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
|
||||
- if (!check_vif_up(vif))
|
||||
- return -EIO;
|
||||
-
|
||||
- err = brcmf_cfg80211_escan(wiphy, vif, request);
|
||||
-
|
||||
- if (err)
|
||||
- brcmf_err("scan error (%d)\n", err);
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Exit\n");
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
|
||||
{
|
||||
s32 err = 0;
|
|
@ -0,0 +1,86 @@
|
|||
From bbf35414cd23a9d7230bfd7046e1e2c26020e7eb Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:36 +0100
|
||||
Subject: [PATCH] brcmfmac: get rid of struct brcmf_cfg80211_info::active_scan
|
||||
field
|
||||
|
||||
The field struct brcmf_cfg80211_info::active_scan is set to true upon
|
||||
initializing the driver instance, but it is never changed so simply
|
||||
get rid of it.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +---------
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 --
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 5 +----
|
||||
3 files changed, 2 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1043,7 +1043,6 @@ brcmf_do_escan(struct brcmf_if *ifp, str
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
|
||||
s32 err;
|
||||
- u32 passive_scan;
|
||||
struct brcmf_scan_results *results;
|
||||
struct escan_info *escan = &cfg->escan_info;
|
||||
|
||||
@@ -1051,13 +1050,7 @@ brcmf_do_escan(struct brcmf_if *ifp, str
|
||||
escan->ifp = ifp;
|
||||
escan->wiphy = cfg->wiphy;
|
||||
escan->escan_state = WL_ESCAN_STATE_SCANNING;
|
||||
- passive_scan = cfg->active_scan ? 0 : 1;
|
||||
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
|
||||
- passive_scan);
|
||||
- if (err) {
|
||||
- brcmf_err("error (%d)\n", err);
|
||||
- return err;
|
||||
- }
|
||||
+
|
||||
brcmf_scan_config_mpc(ifp, 0);
|
||||
results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
|
||||
results->version = 0;
|
||||
@@ -5767,7 +5760,6 @@ static s32 wl_init_priv(struct brcmf_cfg
|
||||
|
||||
cfg->scan_request = NULL;
|
||||
cfg->pwr_save = true;
|
||||
- cfg->active_scan = true; /* we do active scan per default */
|
||||
cfg->dongle_up = false; /* dongle is not up yet */
|
||||
err = brcmf_init_priv_mem(cfg);
|
||||
if (err)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -283,7 +283,6 @@ struct brcmf_cfg80211_wowl {
|
||||
* @scan_status: scan activity on the dongle.
|
||||
* @pub: common driver information.
|
||||
* @channel: current channel.
|
||||
- * @active_scan: current scan mode.
|
||||
* @int_escan_map: bucket map for which internal e-scan is done.
|
||||
* @ibss_starter: indicates this sta is ibss starter.
|
||||
* @pwr_save: indicate whether dongle to support power save mode.
|
||||
@@ -316,7 +315,6 @@ struct brcmf_cfg80211_info {
|
||||
unsigned long scan_status;
|
||||
struct brcmf_pub *pub;
|
||||
u32 channel;
|
||||
- bool active_scan;
|
||||
u32 int_escan_map;
|
||||
bool ibss_starter;
|
||||
bool pwr_save;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -692,10 +692,7 @@ static s32 brcmf_p2p_escan(struct brcmf_
|
||||
|
||||
/* determine the scan engine parameters */
|
||||
sparams->bss_type = DOT11_BSSTYPE_ANY;
|
||||
- if (p2p->cfg->active_scan)
|
||||
- sparams->scan_type = 0;
|
||||
- else
|
||||
- sparams->scan_type = 1;
|
||||
+ sparams->scan_type = BRCMF_SCANTYPE_ACTIVE;
|
||||
|
||||
eth_broadcast_addr(sparams->bssid);
|
||||
sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS);
|
|
@ -0,0 +1,55 @@
|
|||
From bd99a3013bdc00f8fc7534c657b39616792b4467 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 8 Nov 2017 14:36:37 +0100
|
||||
Subject: [PATCH] brcmfmac: move configuration of probe request IEs
|
||||
|
||||
The configuration of the IEs for probe requests was done in a P2P
|
||||
related function, which is not very obvious. Moving it to
|
||||
.scan callback function, ie. brcmf_cfg80211_scan().
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 6 ++----
|
||||
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1108,6 +1108,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
|
||||
if (err)
|
||||
goto scan_out;
|
||||
|
||||
+ err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
|
||||
+ request->ie, request->ie_len);
|
||||
+ if (err)
|
||||
+ goto scan_out;
|
||||
+
|
||||
err = brcmf_do_escan(vif->ifp, request);
|
||||
if (err)
|
||||
goto scan_out;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -881,7 +881,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_p2p_info *p2p = &cfg->p2p;
|
||||
- int err = 0;
|
||||
+ int err;
|
||||
|
||||
if (brcmf_p2p_scan_is_p2p_request(request)) {
|
||||
/* find my listen channel */
|
||||
@@ -904,9 +904,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi
|
||||
/* override .run_escan() callback. */
|
||||
cfg->escan_info.run = brcmf_p2p_run_escan;
|
||||
}
|
||||
- err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
|
||||
- request->ie, request->ie_len);
|
||||
- return err;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,434 @@
|
|||
From fdd0bd88ceaecf729db103ac8836af5805dd2dc1 Mon Sep 17 00:00:00 2001
|
||||
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
|
||||
Date: Fri, 10 Nov 2017 17:27:15 +0800
|
||||
Subject: [PATCH] brcmfmac: add CLM download support
|
||||
|
||||
The firmware for brcmfmac devices includes information regarding
|
||||
regulatory constraints. For certain devices this information is kept
|
||||
separately in a binary form that needs to be downloaded to the device.
|
||||
This patch adds support to download this so-called CLM blob file. It
|
||||
uses the same naming scheme as the other firmware files with extension
|
||||
of .clm_blob.
|
||||
|
||||
The CLM blob file is optional. If the file does not exist, the download
|
||||
process will be bypassed. It will not affect the driver loading.
|
||||
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 10 ++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 157 +++++++++++++++++++++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 +
|
||||
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 31 ++++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 19 +++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 19 +++
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 18 +++
|
||||
8 files changed, 258 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd {
|
||||
* @wowl_config: specify if dongle is configured for wowl when going to suspend
|
||||
* @get_ramsize: obtain size of device memory.
|
||||
* @get_memdump: obtain device memory dump in provided buffer.
|
||||
+ * @get_fwname: obtain firmware name.
|
||||
*
|
||||
* This structure provides an abstract interface towards the
|
||||
* bus specific driver. For control messages to common driver
|
||||
@@ -87,6 +88,8 @@ struct brcmf_bus_ops {
|
||||
void (*wowl_config)(struct device *dev, bool enabled);
|
||||
size_t (*get_ramsize)(struct device *dev);
|
||||
int (*get_memdump)(struct device *dev, void *data, size_t len);
|
||||
+ int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
|
||||
+ unsigned char *fw_name);
|
||||
};
|
||||
|
||||
|
||||
@@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_b
|
||||
return bus->ops->get_memdump(bus->dev, data, len);
|
||||
}
|
||||
|
||||
+static inline
|
||||
+int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
|
||||
+ unsigned char *fw_name)
|
||||
+{
|
||||
+ return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* interface functions from common layer
|
||||
*/
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/firmware.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "core.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "tracepoint.h"
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
+#include "firmware.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
@@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct
|
||||
brcmf_err("Set join_pref error (%d)\n", err);
|
||||
}
|
||||
|
||||
+static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
|
||||
+ struct brcmf_dload_data_le *dload_buf,
|
||||
+ u32 len)
|
||||
+{
|
||||
+ s32 err;
|
||||
+
|
||||
+ flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
|
||||
+ dload_buf->flag = cpu_to_le16(flag);
|
||||
+ dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
|
||||
+ dload_buf->len = cpu_to_le32(len);
|
||||
+ dload_buf->crc = cpu_to_le32(0);
|
||||
+ len = sizeof(*dload_buf) + len - 1;
|
||||
+
|
||||
+ err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
|
||||
+{
|
||||
+ struct brcmf_bus *bus = ifp->drvr->bus_if;
|
||||
+ struct brcmf_rev_info *ri = &ifp->drvr->revinfo;
|
||||
+ u8 fw_name[BRCMF_FW_NAME_LEN];
|
||||
+ u8 *ptr;
|
||||
+ size_t len;
|
||||
+ s32 err;
|
||||
+
|
||||
+ memset(fw_name, 0, BRCMF_FW_NAME_LEN);
|
||||
+ err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name);
|
||||
+ if (err) {
|
||||
+ brcmf_err("get firmware name failed (%d)\n", err);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* generate CLM blob file name */
|
||||
+ ptr = strrchr(fw_name, '.');
|
||||
+ if (!ptr) {
|
||||
+ err = -ENOENT;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ len = ptr - fw_name + 1;
|
||||
+ if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
|
||||
+ err = -E2BIG;
|
||||
+ } else {
|
||||
+ strlcpy(clm_name, fw_name, len);
|
||||
+ strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
|
||||
+ }
|
||||
+done:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
|
||||
+{
|
||||
+ struct device *dev = ifp->drvr->bus_if->dev;
|
||||
+ struct brcmf_dload_data_le *chunk_buf;
|
||||
+ const struct firmware *clm = NULL;
|
||||
+ u8 clm_name[BRCMF_FW_NAME_LEN];
|
||||
+ u32 chunk_len;
|
||||
+ u32 datalen;
|
||||
+ u32 cumulative_len;
|
||||
+ u16 dl_flag = DL_BEGIN;
|
||||
+ u32 status;
|
||||
+ s32 err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+
|
||||
+ memset(clm_name, 0, BRCMF_FW_NAME_LEN);
|
||||
+ err = brcmf_c_get_clm_name(ifp, clm_name);
|
||||
+ if (err) {
|
||||
+ brcmf_err("get CLM blob file name failed (%d)\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = request_firmware(&clm, clm_name, dev);
|
||||
+ if (err) {
|
||||
+ if (err == -ENOENT) {
|
||||
+ brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ brcmf_err("request CLM blob file failed (%d)\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
|
||||
+ if (!chunk_buf) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ datalen = clm->size;
|
||||
+ cumulative_len = 0;
|
||||
+ do {
|
||||
+ if (datalen > MAX_CHUNK_LEN) {
|
||||
+ chunk_len = MAX_CHUNK_LEN;
|
||||
+ } else {
|
||||
+ chunk_len = datalen;
|
||||
+ dl_flag |= DL_END;
|
||||
+ }
|
||||
+ memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
|
||||
+
|
||||
+ err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
|
||||
+
|
||||
+ dl_flag &= ~DL_BEGIN;
|
||||
+
|
||||
+ cumulative_len += chunk_len;
|
||||
+ datalen -= chunk_len;
|
||||
+ } while ((datalen > 0) && (err == 0));
|
||||
+
|
||||
+ if (err) {
|
||||
+ brcmf_err("clmload (%zu byte file) failed (%d); ",
|
||||
+ clm->size, err);
|
||||
+ /* Retrieve clmload_status and print */
|
||||
+ err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
|
||||
+ if (err)
|
||||
+ brcmf_err("get clmload_status failed (%d)\n", err);
|
||||
+ else
|
||||
+ brcmf_dbg(INFO, "clmload_status=%d\n", status);
|
||||
+ err = -EIO;
|
||||
+ }
|
||||
+
|
||||
+ kfree(chunk_buf);
|
||||
+done:
|
||||
+ release_firmware(clm);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
{
|
||||
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
|
||||
u8 buf[BRCMF_DCMD_SMLEN];
|
||||
struct brcmf_rev_info_le revinfo;
|
||||
struct brcmf_rev_info *ri;
|
||||
+ char *clmver;
|
||||
char *ptr;
|
||||
s32 err;
|
||||
|
||||
@@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
|
||||
}
|
||||
ri->result = err;
|
||||
|
||||
+ /* Do any CLM downloading */
|
||||
+ err = brcmf_c_process_clm_blob(ifp);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("download CLM blob file failed, %d\n", err);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
/* query for 'ver' to get version info from firmware */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
strcpy(buf, "ver");
|
||||
@@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
|
||||
ptr = strrchr(buf, ' ') + 1;
|
||||
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
|
||||
|
||||
+ /* Query for 'clmver' to get CLM version info from firmware */
|
||||
+ memset(buf, 0, sizeof(buf));
|
||||
+ err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
|
||||
+ if (err) {
|
||||
+ brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
|
||||
+ } else {
|
||||
+ clmver = (char *)buf;
|
||||
+ /* store CLM version for adding it to revinfo debugfs file */
|
||||
+ memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
|
||||
+
|
||||
+ /* Replace all newline/linefeed characters with space
|
||||
+ * character
|
||||
+ */
|
||||
+ ptr = clmver;
|
||||
+ while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL)
|
||||
+ *ptr = ' ';
|
||||
+
|
||||
+ brcmf_dbg(INFO, "CLM version = %s\n", clmver);
|
||||
+ }
|
||||
+
|
||||
/* set mpc */
|
||||
err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
|
||||
if (err) {
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1009,6 +1009,8 @@ static int brcmf_revinfo_read(struct seq
|
||||
seq_printf(s, "anarev: %u\n", ri->anarev);
|
||||
seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
|
||||
|
||||
+ seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -141,6 +141,8 @@ struct brcmf_pub {
|
||||
struct notifier_block inetaddr_notifier;
|
||||
struct notifier_block inet6addr_notifier;
|
||||
struct brcmf_mp_device *settings;
|
||||
+
|
||||
+ u8 clmver[BRCMF_DCMD_SMLEN];
|
||||
};
|
||||
|
||||
/* forward declarations */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
@@ -155,6 +155,21 @@
|
||||
#define BRCMF_MFP_CAPABLE 1
|
||||
#define BRCMF_MFP_REQUIRED 2
|
||||
|
||||
+/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
|
||||
+ * ioctl. It is relatively small because firmware has small maximum size input
|
||||
+ * playload restriction for ioctls.
|
||||
+ */
|
||||
+#define MAX_CHUNK_LEN 1400
|
||||
+
|
||||
+#define DLOAD_HANDLER_VER 1 /* Downloader version */
|
||||
+#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
|
||||
+#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
|
||||
+
|
||||
+#define DL_BEGIN 0x0002
|
||||
+#define DL_END 0x0004
|
||||
+
|
||||
+#define DL_TYPE_CLM 2
|
||||
+
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
@@ -827,6 +842,22 @@ struct brcmf_pno_macaddr_le {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * struct brcmf_dload_data_le - data passing to firmware for downloading
|
||||
+ * @flag: flags related to download data.
|
||||
+ * @dload_type: type of download data.
|
||||
+ * @len: length in bytes of download data.
|
||||
+ * @crc: crc of download data.
|
||||
+ * @data: download data.
|
||||
+ */
|
||||
+struct brcmf_dload_data_le {
|
||||
+ __le16 flag;
|
||||
+ __le16 dload_type;
|
||||
+ __le32 len;
|
||||
+ __le32 crc;
|
||||
+ u8 data[1];
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct brcmf_pno_bssid_le - bssid configuration for PNO scan.
|
||||
*
|
||||
* @bssid: BSS network identifier.
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev,
|
||||
+ u8 *fw_name)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
|
||||
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (devinfo->fw_name[0] != '\0')
|
||||
+ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
|
||||
+ else
|
||||
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
|
||||
+ brcmf_pcie_fwnames,
|
||||
+ ARRAY_SIZE(brcmf_pcie_fwnames),
|
||||
+ fw_name, NULL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
|
||||
.txdata = brcmf_pcie_tx,
|
||||
@@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_
|
||||
.wowl_config = brcmf_pcie_wowl_config,
|
||||
.get_ramsize = brcmf_pcie_get_ramsize,
|
||||
.get_memdump = brcmf_pcie_get_memdump,
|
||||
+ .get_fwname = brcmf_pcie_get_fwname,
|
||||
};
|
||||
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3985,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data)
|
||||
}
|
||||
}
|
||||
|
||||
+static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev,
|
||||
+ u8 *fw_name)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (sdiodev->fw_name[0] != '\0')
|
||||
+ strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN);
|
||||
+ else
|
||||
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
|
||||
+ brcmf_sdio_fwnames,
|
||||
+ ARRAY_SIZE(brcmf_sdio_fwnames),
|
||||
+ fw_name, NULL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||
.stop = brcmf_sdio_bus_stop,
|
||||
.preinit = brcmf_sdio_bus_preinit,
|
||||
@@ -3995,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_
|
||||
.wowl_config = brcmf_sdio_wowl_config,
|
||||
.get_ramsize = brcmf_sdio_bus_get_ramsize,
|
||||
.get_memdump = brcmf_sdio_bus_get_memdump,
|
||||
+ .get_fwname = brcmf_sdio_get_fwname,
|
||||
};
|
||||
|
||||
static void brcmf_sdio_firmware_callback(struct device *dev, int err,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct
|
||||
device_set_wakeup_enable(devinfo->dev, false);
|
||||
}
|
||||
|
||||
+static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev,
|
||||
+ u8 *fw_name)
|
||||
+{
|
||||
+ struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (devinfo->fw_name[0] != '\0')
|
||||
+ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
|
||||
+ else
|
||||
+ ret = brcmf_fw_map_chip_to_name(chip, chiprev,
|
||||
+ brcmf_usb_fwnames,
|
||||
+ ARRAY_SIZE(brcmf_usb_fwnames),
|
||||
+ fw_name, NULL);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||
.txdata = brcmf_usb_tx,
|
||||
.stop = brcmf_usb_down,
|
||||
.txctl = brcmf_usb_tx_ctlpkt,
|
||||
.rxctl = brcmf_usb_rx_ctlpkt,
|
||||
.wowl_config = brcmf_usb_wowl_config,
|
||||
+ .get_fwname = brcmf_usb_get_fwname,
|
||||
};
|
||||
|
||||
static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
|
|
@ -0,0 +1,37 @@
|
|||
From 5c3de777bdaf48bd0cfb43097c0d0fb85056cab7 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Sat, 25 Nov 2017 21:39:25 +0100
|
||||
Subject: [PATCH] brcmfmac: change driver unbind order of the sdio function
|
||||
devices
|
||||
|
||||
In the function brcmf_sdio_firmware_callback() the driver is
|
||||
unbound from the sdio function devices in the error path.
|
||||
However, the order in which it is done resulted in a use-after-free
|
||||
issue (see brcmf_ops_sdio_remove() in bcmsdh.c). Hence change
|
||||
the order and first unbind sdio function #2 device and then
|
||||
unbind sdio function #1 device.
|
||||
|
||||
Cc: stable@vger.kernel.org # v4.12.x
|
||||
Fixes: 7a51461fc2da ("brcmfmac: unbind all devices upon failure in firmware callback")
|
||||
Reported-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -4121,8 +4121,8 @@ release:
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
fail:
|
||||
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
|
||||
- device_release_driver(dev);
|
||||
device_release_driver(&sdiodev->func[2]->dev);
|
||||
+ device_release_driver(dev);
|
||||
}
|
||||
|
||||
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|
@ -0,0 +1,33 @@
|
|||
From 51ef7925e10688c57186d438e784532e063492e4 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Date: Thu, 23 Nov 2017 17:57:04 +0200
|
||||
Subject: [PATCH] brcmfmac: Avoid build error with make W=1
|
||||
|
||||
When I run make W=1 on gcc (Debian 7.2.0-16) 7.2.0 I got an error for
|
||||
the first run, all next ones are okay.
|
||||
|
||||
CC [M] drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2078: error: Cannot parse struct or union!
|
||||
scripts/Makefile.build:310: recipe for target 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o' failed
|
||||
|
||||
Seems like something happened with W=1 and wrong kernel doc format.
|
||||
As a quick fix remove dubious /** in the code.
|
||||
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(stru
|
||||
return head_pad;
|
||||
}
|
||||
|
||||
-/**
|
||||
+/*
|
||||
* struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
|
||||
* bus layer usage.
|
||||
*/
|
|
@ -0,0 +1,40 @@
|
|||
From cc124d5cc8d81985c3511892d7a6d546552ff754 Mon Sep 17 00:00:00 2001
|
||||
From: Wright Feng <wright.feng@cypress.com>
|
||||
Date: Tue, 16 Jan 2018 17:26:50 +0800
|
||||
Subject: [PATCH] brcmfmac: fix CLM load error for legacy chips when user
|
||||
helper is enabled
|
||||
|
||||
For legacy chips without CLM blob files, kernel with user helper function
|
||||
returns -EAGAIN when we request_firmware(), and then driver got failed
|
||||
when bringing up legacy chips. We expect the CLM blob file for legacy chip
|
||||
is not existence in firmware path, but the -ENOENT error is transferred to
|
||||
-EAGAIN in firmware_class.c with user helper.
|
||||
Because of that, we continue with CLM data currently present in firmware
|
||||
if getting error from doing request_firmware().
|
||||
|
||||
Cc: stable@vger.kernel.org # v4.15.y
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -182,12 +182,9 @@ static int brcmf_c_process_clm_blob(stru
|
||||
|
||||
err = request_firmware(&clm, clm_name, dev);
|
||||
if (err) {
|
||||
- if (err == -ENOENT) {
|
||||
- brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n");
|
||||
- return 0;
|
||||
- }
|
||||
- brcmf_err("request CLM blob file failed (%d)\n", err);
|
||||
- return err;
|
||||
+ brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n",
|
||||
+ err);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
|
|
@ -0,0 +1,103 @@
|
|||
From 9df7ddc3ed25b7d3473f117a0680b9418adb5753 Mon Sep 17 00:00:00 2001
|
||||
Message-Id: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
|
||||
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Date: Mon, 27 Nov 2017 18:56:22 +0100
|
||||
Subject: [PATCH 1/2] ath9k: move spectral scan support under a separate config
|
||||
symbol
|
||||
|
||||
At the moment, spectral scan support, and with it RELAY, is always enabled
|
||||
with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user
|
||||
of RELAY in ath9k, and it unconditionally reserves a relay channel.
|
||||
|
||||
Having debugfs support in ath9k is often useful even on very small embedded
|
||||
routers, where we'd rather like to avoid the code size and RAM usage of the
|
||||
relay support.
|
||||
|
||||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath9k/Kconfig | 14 ++++++++++----
|
||||
drivers/net/wireless/ath/ath9k/Makefile | 4 ++--
|
||||
drivers/net/wireless/ath/ath9k/common-spectral.h | 4 ++--
|
||||
3 files changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
@@ -64,13 +64,12 @@ config ATH9K_DEBUGFS
|
||||
depends on ATH9K && DEBUG_FS
|
||||
select MAC80211_DEBUGFS
|
||||
select ATH9K_COMMON_DEBUG
|
||||
- depends on RELAY
|
||||
---help---
|
||||
Say Y, if you need access to ath9k's statistics for
|
||||
interrupts, rate control, etc.
|
||||
|
||||
- Also required for changing debug message flags at run time.
|
||||
- As well as access to the FFT/spectral data and TX99.
|
||||
+ Also required for changing debug message flags at run time and for
|
||||
+ TX99.
|
||||
|
||||
config ATH9K_STATION_STATISTICS
|
||||
bool "Detailed station statistics"
|
||||
@@ -181,7 +180,6 @@ config ATH9K_HTC_DEBUGFS
|
||||
bool "Atheros ath9k_htc debugging"
|
||||
depends on ATH9K_HTC && DEBUG_FS
|
||||
select ATH9K_COMMON_DEBUG
|
||||
- depends on RELAY
|
||||
---help---
|
||||
Say Y, if you need access to ath9k_htc's statistics.
|
||||
As well as access to the FFT/spectral data.
|
||||
@@ -197,3 +195,11 @@ config ATH9K_HWRNG
|
||||
|
||||
Say Y, feeds the entropy directly from the WiFi driver to the input
|
||||
pool.
|
||||
+
|
||||
+config ATH9K_COMMON_SPECTRAL
|
||||
+ bool "Atheros ath9k/ath9k_htc spectral scan support"
|
||||
+ depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS
|
||||
+ depends on RELAY
|
||||
+ default n
|
||||
+ ---help---
|
||||
+ Say Y to enable access to the FFT/spectral data via debugfs.
|
||||
--- a/drivers/net/wireless/ath/ath9k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Makefile
|
||||
@@ -61,8 +61,8 @@ ath9k_common-y:= common.o \
|
||||
common-init.o \
|
||||
common-beacon.o \
|
||||
|
||||
-ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o \
|
||||
- common-spectral.o
|
||||
+ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o
|
||||
+ath9k_common-$(CPTCFG_ATH9K_COMMON_SPECTRAL) += common-spectral.o
|
||||
|
||||
ath9k_htc-y += htc_hst.o \
|
||||
hif_usb.o \
|
||||
--- a/drivers/net/wireless/ath/ath9k/common-spectral.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.h
|
||||
@@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight(
|
||||
return bins[0] & 0x3f;
|
||||
}
|
||||
|
||||
-#ifdef CPTCFG_ATH9K_COMMON_DEBUG
|
||||
+#ifdef CPTCFG_ATH9K_COMMON_SPECTRAL
|
||||
void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
|
||||
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
|
||||
|
||||
@@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(st
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
-#endif /* CPTCFG_ATH9K_COMMON_DEBUG */
|
||||
+#endif /* CPTCFG_ATH9K_COMMON_SPECTRAL */
|
||||
|
||||
#endif /* SPECTRAL_H */
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -116,6 +116,7 @@ ATH9K_PCOEM=
|
||||
ATH9K_HTC=
|
||||
ATH9K_HTC_DEBUGFS=
|
||||
ATH9K_HWRNG=
|
||||
+ATH9K_COMMON_SPECTRAL=
|
||||
CARL9170=
|
||||
CARL9170_LEDS=
|
||||
CARL9170_DEBUGFS=
|
|
@ -0,0 +1,91 @@
|
|||
From 42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61 Mon Sep 17 00:00:00 2001
|
||||
Message-Id: <42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61.1515610034.git.mschiffer@universe-factory.net>
|
||||
In-Reply-To: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
|
||||
References: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net>
|
||||
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Date: Mon, 27 Nov 2017 18:56:23 +0100
|
||||
Subject: [PATCH 2/2] ath10k: move spectral scan support under a separate
|
||||
config symbol
|
||||
|
||||
At the moment, spectral scan support, and with it RELAY, is always enabled
|
||||
with ATH10K_DEBUGFS. Spectral scan support is currently the only user of
|
||||
RELAY in ath10k, and it unconditionally reserves a relay channel.
|
||||
|
||||
Having debugfs support in ath10k is often useful even on very small
|
||||
embedded routers, where we'd rather like to avoid the code size and RAM
|
||||
usage of the relay support. While ath10k-based devices usually have more
|
||||
resources than ath9k-based ones, it makes sense to keep the configuration
|
||||
symmetric to ath9k, so the same base kernel without RELAY can be used for
|
||||
both ath9k and ath10k hardware.
|
||||
|
||||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/Kconfig | 9 ++++++++-
|
||||
drivers/net/wireless/ath/ath10k/Makefile | 2 +-
|
||||
drivers/net/wireless/ath/ath10k/spectral.h | 4 ++--
|
||||
3 files changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
@@ -51,12 +51,19 @@ config ATH10K_DEBUG
|
||||
config ATH10K_DEBUGFS
|
||||
bool "Atheros ath10k debugfs support"
|
||||
depends on ATH10K && DEBUG_FS
|
||||
- depends on RELAY
|
||||
---help---
|
||||
Enabled debugfs support
|
||||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
+config ATH10K_SPECTRAL
|
||||
+ bool "Atheros ath10k spectral scan support"
|
||||
+ depends on ATH10K_DEBUGFS
|
||||
+ depends on RELAY
|
||||
+ default n
|
||||
+ ---help---
|
||||
+ Say Y to enable access to the FFT/spectral data via debugfs.
|
||||
+
|
||||
config ATH10K_TRACING
|
||||
depends on !KERNEL_3_4
|
||||
bool "Atheros ath10k tracing support"
|
||||
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
||||
@@ -14,7 +14,7 @@ ath10k_core-y += mac.o \
|
||||
p2p.o \
|
||||
swap.o
|
||||
|
||||
-ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o
|
||||
+ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
|
||||
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
||||
--- a/drivers/net/wireless/ath/ath10k/spectral.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/spectral.h
|
||||
@@ -44,7 +44,7 @@ enum ath10k_spectral_mode {
|
||||
SPECTRAL_MANUAL,
|
||||
};
|
||||
|
||||
-#ifdef CPTCFG_ATH10K_DEBUGFS
|
||||
+#ifdef CPTCFG_ATH10K_SPECTRAL
|
||||
|
||||
int ath10k_spectral_process_fft(struct ath10k *ar,
|
||||
struct wmi_phyerr_ev_arg *phyerr,
|
||||
@@ -85,6 +85,6 @@ static inline void ath10k_spectral_destr
|
||||
{
|
||||
}
|
||||
|
||||
-#endif /* CPTCFG_ATH10K_DEBUGFS */
|
||||
+#endif /* CPTCFG_ATH10K_SPECTRAL */
|
||||
|
||||
#endif /* SPECTRAL_H */
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -140,6 +140,7 @@ ATH10K_SDIO=
|
||||
ATH10K_USB=
|
||||
ATH10K_DEBUG=
|
||||
ATH10K_DEBUGFS=
|
||||
+ATH10K_SPECTRAL=
|
||||
ATH10K_THERMAL=
|
||||
ATH10K_TRACING=
|
||||
ATH10K_DFS_CERTIFIED=
|
|
@ -0,0 +1,25 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 17 Jan 2018 11:11:17 +0100
|
||||
Subject: [PATCH] ath9k: discard undersized packets
|
||||
|
||||
Sometimes the hardware will push small packets that trigger a WARN_ON
|
||||
in mac80211. Discard them early to avoid this issue.
|
||||
|
||||
Reported-by: Stijn Tintel <stijn@linux-ipv6.be>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/recv.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/recv.c
|
||||
@@ -826,9 +826,9 @@ static int ath9k_rx_skb_preprocess(struc
|
||||
sc->rx.discard_next = false;
|
||||
|
||||
/*
|
||||
- * Discard zero-length packets.
|
||||
+ * Discard zero-length packets and packets smaller than an ACK
|
||||
*/
|
||||
- if (!rx_stats->rs_datalen) {
|
||||
+ if (rx_stats->rs_datalen < 10) {
|
||||
RX_STAT_INC(rx_len_err);
|
||||
goto corrupt;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
From 1fd3ae124d5e675f57cf7e3c601fb8f7712e0329 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:38 +0100
|
||||
Subject: [PATCH] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb()
|
||||
|
||||
All the other IO functions are the other way round in this
|
||||
driver. Make this one match.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -230,8 +230,8 @@ void brcmf_sdiod_change_state(struct brc
|
||||
sdiodev->state = state;
|
||||
}
|
||||
|
||||
-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
|
||||
- uint regaddr, u8 byte)
|
||||
+static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
|
||||
+ uint regaddr)
|
||||
{
|
||||
int err_ret;
|
||||
|
||||
@@ -269,8 +269,8 @@ static int brcmf_sdiod_request_data(stru
|
||||
if (fn)
|
||||
sdio_writeb(func, *(u8 *)data, addr, &ret);
|
||||
else
|
||||
- ret = brcmf_sdiod_f0_writeb(func, addr,
|
||||
- *(u8 *)data);
|
||||
+ ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
|
||||
+ addr);
|
||||
} else {
|
||||
if (fn)
|
||||
*(u8 *)data = sdio_readb(func, addr, &ret);
|
|
@ -0,0 +1,105 @@
|
|||
From 1e6f676f43aa4270ebc5cff8e32a55f72362e042 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:39 +0100
|
||||
Subject: [PATCH] brcmfmac: Register sizes on hardware are not dependent on
|
||||
compiler types
|
||||
|
||||
The 4 IO functions in this patch are incorrect as they use compiler types
|
||||
to determine how many bytes to send to the hardware.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -264,7 +264,7 @@ static int brcmf_sdiod_request_data(stru
|
||||
func = sdiodev->func[fn];
|
||||
|
||||
switch (regsz) {
|
||||
- case sizeof(u8):
|
||||
+ case 1:
|
||||
if (write) {
|
||||
if (fn)
|
||||
sdio_writeb(func, *(u8 *)data, addr, &ret);
|
||||
@@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(stru
|
||||
*(u8 *)data = sdio_f0_readb(func, addr, &ret);
|
||||
}
|
||||
break;
|
||||
- case sizeof(u16):
|
||||
+ case 2:
|
||||
if (write)
|
||||
sdio_writew(func, *(u16 *)data, addr, &ret);
|
||||
else
|
||||
*(u16 *)data = sdio_readw(func, addr, &ret);
|
||||
break;
|
||||
- case sizeof(u32):
|
||||
+ case 4:
|
||||
if (write)
|
||||
sdio_writel(func, *(u32 *)data, addr, &ret);
|
||||
else
|
||||
@@ -368,7 +368,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc
|
||||
for (i = 0; i < 3; i++) {
|
||||
err = brcmf_sdiod_regrw_helper(sdiodev,
|
||||
SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
- sizeof(u8), &addr[i], true);
|
||||
+ 1, &addr[i], true);
|
||||
if (err) {
|
||||
brcmf_err("failed at addr: 0x%0x\n",
|
||||
SBSDIO_FUNC1_SBADDRLOW + i);
|
||||
@@ -407,7 +407,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
|
||||
+ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
|
||||
false);
|
||||
brcmf_dbg(SDIO, "data:0x%02x\n", data);
|
||||
|
||||
@@ -423,10 +423,10 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
|
||||
+ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
|
||||
false);
|
||||
brcmf_dbg(SDIO, "data:0x%08x\n", data);
|
||||
|
||||
@@ -443,7 +443,7 @@ void brcmf_sdiod_regwb(struct brcmf_sdio
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
|
||||
+ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
|
||||
true);
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
@@ -455,10 +455,10 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
|
||||
+ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
|
||||
true);
|
||||
|
||||
done:
|
||||
@@ -876,7 +876,7 @@ int brcmf_sdiod_abort(struct brcmf_sdio_
|
||||
|
||||
/* issue abort cmd52 command through F0 */
|
||||
brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
|
||||
- sizeof(t_func), &t_func, true);
|
||||
+ 1, &t_func, true);
|
||||
|
||||
brcmf_dbg(SDIO, "Exit\n");
|
||||
return 0;
|
|
@ -0,0 +1,179 @@
|
|||
From 0fcc9fe0048422d66bb906eaa73cc75e11ff7345 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:40 +0100
|
||||
Subject: [PATCH] brcmfmac: Split brcmf_sdiod_regrw_helper() up.
|
||||
|
||||
This large function is concealing a LOT of obscure logic about
|
||||
how the hardware functions. Time to split it up.
|
||||
|
||||
This first patch splits the function into two pieces - read and write,
|
||||
doing away with the rw flag in the process.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 94 +++++++++++++++++-----
|
||||
1 file changed, 73 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -302,8 +302,8 @@ static int brcmf_sdiod_request_data(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
- u8 regsz, void *data, bool write)
|
||||
+static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
+ u8 regsz, void *data)
|
||||
{
|
||||
u8 func;
|
||||
s32 retry = 0;
|
||||
@@ -324,13 +324,66 @@ static int brcmf_sdiod_regrw_helper(stru
|
||||
func = SDIO_FUNC_1;
|
||||
|
||||
do {
|
||||
- if (!write)
|
||||
- memset(data, 0, regsz);
|
||||
/* for retry wait for 1 ms till bus get settled down */
|
||||
if (retry)
|
||||
usleep_range(1000, 2000);
|
||||
+
|
||||
+ ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
|
||||
+ data, true);
|
||||
+
|
||||
+ } while (ret != 0 && ret != -ENOMEDIUM &&
|
||||
+ retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
|
||||
+
|
||||
+ if (ret == -ENOMEDIUM) {
|
||||
+ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
+ } else if (ret != 0) {
|
||||
+ /*
|
||||
+ * SleepCSR register access can fail when
|
||||
+ * waking up the device so reduce this noise
|
||||
+ * in the logs.
|
||||
+ */
|
||||
+ if (addr != SBSDIO_FUNC1_SLEEPCSR)
|
||||
+ brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
|
||||
+ func, addr, ret);
|
||||
+ else
|
||||
+ brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n",
|
||||
+ func, addr, ret);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
+ u8 regsz, void *data)
|
||||
+{
|
||||
+ u8 func;
|
||||
+ s32 retry = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
+ return -ENOMEDIUM;
|
||||
+
|
||||
+ /*
|
||||
+ * figure out how to read the register based on address range
|
||||
+ * 0x00 ~ 0x7FF: function 0 CCCR and FBR
|
||||
+ * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
|
||||
+ * The rest: function 1 silicon backplane core registers
|
||||
+ */
|
||||
+ if ((addr & ~REG_F0_REG_MASK) == 0)
|
||||
+ func = SDIO_FUNC_0;
|
||||
+ else
|
||||
+ func = SDIO_FUNC_1;
|
||||
+
|
||||
+ do {
|
||||
+ memset(data, 0, regsz);
|
||||
+
|
||||
+ /* for retry wait for 1 ms till bus get settled down */
|
||||
+ if (retry)
|
||||
+ usleep_range(1000, 2000);
|
||||
+
|
||||
ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
|
||||
- data, write);
|
||||
+ data, false);
|
||||
+
|
||||
} while (ret != 0 && ret != -ENOMEDIUM &&
|
||||
retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
|
||||
|
||||
@@ -343,12 +396,13 @@ static int brcmf_sdiod_regrw_helper(stru
|
||||
* in the logs.
|
||||
*/
|
||||
if (addr != SBSDIO_FUNC1_SLEEPCSR)
|
||||
- brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
|
||||
- write ? "write" : "read", func, addr, ret);
|
||||
+ brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
|
||||
+ func, addr, ret);
|
||||
else
|
||||
- brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
|
||||
- write ? "write" : "read", func, addr, ret);
|
||||
+ brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n",
|
||||
+ func, addr, ret);
|
||||
}
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -366,13 +420,11 @@ brcmf_sdiod_set_sbaddr_window(struct brc
|
||||
addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
- err = brcmf_sdiod_regrw_helper(sdiodev,
|
||||
- SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
- 1, &addr[i], true);
|
||||
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i],
|
||||
+ &err);
|
||||
if (err) {
|
||||
brcmf_err("failed at addr: 0x%0x\n",
|
||||
SBSDIO_FUNC1_SBADDRLOW + i);
|
||||
- break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,8 +459,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
|
||||
- false);
|
||||
+ retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data);
|
||||
brcmf_dbg(SDIO, "data:0x%02x\n", data);
|
||||
|
||||
if (ret)
|
||||
@@ -426,8 +477,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
|
||||
- false);
|
||||
+
|
||||
+ retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data);
|
||||
+
|
||||
brcmf_dbg(SDIO, "data:0x%08x\n", data);
|
||||
|
||||
done:
|
||||
@@ -443,8 +495,8 @@ void brcmf_sdiod_regwb(struct brcmf_sdio
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
|
||||
- true);
|
||||
+ retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data);
|
||||
+
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
}
|
||||
@@ -458,8 +510,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
|
||||
- true);
|
||||
+
|
||||
+ retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data);
|
||||
|
||||
done:
|
||||
if (ret)
|
|
@ -0,0 +1,62 @@
|
|||
From b9b0d290bc0c90a5a262bc89c9d995988ea98669 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:41 +0100
|
||||
Subject: [PATCH] brcmfmac: Clean up brcmf_sdiod_set_sbaddr_window()
|
||||
|
||||
This function sets the address of the IO window used for
|
||||
SDIO accesses onto the backplane of the chip.
|
||||
|
||||
It currently uses 3 separate masks despite the full mask being
|
||||
defined in the code already. Remove the separate masks and clean up.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 17 +++++------------
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 3 ---
|
||||
2 files changed, 5 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -410,23 +410,16 @@ static int
|
||||
brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
|
||||
{
|
||||
int err = 0, i;
|
||||
- u8 addr[3];
|
||||
+ u32 addr;
|
||||
|
||||
if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
- addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
|
||||
- addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
|
||||
- addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
|
||||
+ addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
|
||||
|
||||
- for (i = 0; i < 3; i++) {
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i],
|
||||
- &err);
|
||||
- if (err) {
|
||||
- brcmf_err("failed at addr: 0x%0x\n",
|
||||
- SBSDIO_FUNC1_SBADDRLOW + i);
|
||||
- }
|
||||
- }
|
||||
+ for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
|
||||
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
+ addr & 0xff, &err);
|
||||
|
||||
return err;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -133,9 +133,6 @@
|
||||
|
||||
/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
|
||||
|
||||
-#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
|
||||
-#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
|
||||
-#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
|
||||
/* Address bits from SBADDR regs */
|
||||
#define SBSDIO_SBWINDOW_MASK 0xffff8000
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
From ea243e9077b3545f20d93884e91c50ac0719685a Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:42 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove dead IO code
|
||||
|
||||
The value passed to brcmf_sdiod_addrprep() is *always* 4
|
||||
remove this parameter and the unused code to handle it.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++----------
|
||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -425,7 +425,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc
|
||||
}
|
||||
|
||||
static int
|
||||
-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
|
||||
+brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
|
||||
{
|
||||
uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
@@ -439,9 +439,7 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_d
|
||||
}
|
||||
|
||||
*addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
-
|
||||
- if (width == 4)
|
||||
- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
+ *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -467,7 +465,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
|
||||
@@ -500,7 +498,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
if (retval)
|
||||
goto done;
|
||||
|
||||
@@ -736,7 +734,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
@@ -757,7 +755,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
|
||||
addr, pktq->qlen);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
@@ -801,7 +799,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
|
||||
memcpy(mypkt->data, buf, nbytes);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
|
||||
if (!err)
|
||||
err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
|
||||
@@ -821,7 +819,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
|
||||
+ err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From 4a3338ba2a7421db2260159cca5a27bd2ee36d00 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:43 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove bandaid for SleepCSR
|
||||
|
||||
Register access code is not the place for band-aid fixes like this.
|
||||
If this is a genuine problem, it should be fixed further up in the driver
|
||||
stack.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 28 +---------------------
|
||||
1 file changed, 1 insertion(+), 27 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -334,21 +334,8 @@ static int brcmf_sdiod_reg_write(struct
|
||||
} while (ret != 0 && ret != -ENOMEDIUM &&
|
||||
retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
|
||||
|
||||
- if (ret == -ENOMEDIUM) {
|
||||
+ if (ret == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
- } else if (ret != 0) {
|
||||
- /*
|
||||
- * SleepCSR register access can fail when
|
||||
- * waking up the device so reduce this noise
|
||||
- * in the logs.
|
||||
- */
|
||||
- if (addr != SBSDIO_FUNC1_SLEEPCSR)
|
||||
- brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
|
||||
- func, addr, ret);
|
||||
- else
|
||||
- brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n",
|
||||
- func, addr, ret);
|
||||
- }
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -389,19 +376,6 @@ static int brcmf_sdiod_reg_read(struct b
|
||||
|
||||
if (ret == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
- else if (ret != 0) {
|
||||
- /*
|
||||
- * SleepCSR register access can fail when
|
||||
- * waking up the device so reduce this noise
|
||||
- * in the logs.
|
||||
- */
|
||||
- if (addr != SBSDIO_FUNC1_SLEEPCSR)
|
||||
- brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
|
||||
- func, addr, ret);
|
||||
- else
|
||||
- brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n",
|
||||
- func, addr, ret);
|
||||
- }
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,344 @@
|
|||
From 993a98a42e6e790fd0d2bf7d55a031513c7ba7dc Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:44 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_request_data()
|
||||
|
||||
This function is obfuscating how IO works on this chip. Remove it
|
||||
and push its logic into brcmf_sdiod_reg_{read,write}().
|
||||
|
||||
Handling of -ENOMEDIUM is altered, but as that's pretty much broken anyway
|
||||
we can ignore that.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 237 ++++++++-------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 2 +-
|
||||
2 files changed, 87 insertions(+), 152 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -230,6 +230,43 @@ void brcmf_sdiod_change_state(struct brc
|
||||
sdiodev->state = state;
|
||||
}
|
||||
|
||||
+static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
|
||||
+ u32 address)
|
||||
+{
|
||||
+ int err = 0, i;
|
||||
+ u32 addr;
|
||||
+
|
||||
+ if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
+ return -ENOMEDIUM;
|
||||
+
|
||||
+ addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
|
||||
+
|
||||
+ for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
|
||||
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
+ addr & 0xff, &err);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
|
||||
+{
|
||||
+ uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ if (bar0 != sdiodev->sbwad) {
|
||||
+ err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ sdiodev->sbwad = bar0;
|
||||
+ }
|
||||
+
|
||||
+ *addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
|
||||
uint regaddr)
|
||||
{
|
||||
@@ -249,173 +286,84 @@ static inline int brcmf_sdiod_f0_writeb(
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
|
||||
- u32 addr, u8 regsz, void *data, bool write)
|
||||
-{
|
||||
- struct sdio_func *func;
|
||||
- int ret = -EINVAL;
|
||||
-
|
||||
- brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
|
||||
- write, fn, addr, regsz);
|
||||
-
|
||||
- /* only allow byte access on F0 */
|
||||
- if (WARN_ON(regsz > 1 && !fn))
|
||||
- return -EINVAL;
|
||||
- func = sdiodev->func[fn];
|
||||
-
|
||||
- switch (regsz) {
|
||||
- case 1:
|
||||
- if (write) {
|
||||
- if (fn)
|
||||
- sdio_writeb(func, *(u8 *)data, addr, &ret);
|
||||
- else
|
||||
- ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
|
||||
- addr);
|
||||
- } else {
|
||||
- if (fn)
|
||||
- *(u8 *)data = sdio_readb(func, addr, &ret);
|
||||
- else
|
||||
- *(u8 *)data = sdio_f0_readb(func, addr, &ret);
|
||||
- }
|
||||
- break;
|
||||
- case 2:
|
||||
- if (write)
|
||||
- sdio_writew(func, *(u16 *)data, addr, &ret);
|
||||
- else
|
||||
- *(u16 *)data = sdio_readw(func, addr, &ret);
|
||||
- break;
|
||||
- case 4:
|
||||
- if (write)
|
||||
- sdio_writel(func, *(u32 *)data, addr, &ret);
|
||||
- else
|
||||
- *(u32 *)data = sdio_readl(func, addr, &ret);
|
||||
- break;
|
||||
- default:
|
||||
- brcmf_err("invalid size: %d\n", regsz);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (ret)
|
||||
- brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
|
||||
- write ? "write" : "read", fn, addr, ret);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
u8 regsz, void *data)
|
||||
{
|
||||
- u8 func;
|
||||
- s32 retry = 0;
|
||||
int ret;
|
||||
|
||||
- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
- return -ENOMEDIUM;
|
||||
-
|
||||
/*
|
||||
* figure out how to read the register based on address range
|
||||
* 0x00 ~ 0x7FF: function 0 CCCR and FBR
|
||||
* 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
|
||||
* The rest: function 1 silicon backplane core registers
|
||||
+ * f0 writes must be bytewise
|
||||
*/
|
||||
- if ((addr & ~REG_F0_REG_MASK) == 0)
|
||||
- func = SDIO_FUNC_0;
|
||||
- else
|
||||
- func = SDIO_FUNC_1;
|
||||
-
|
||||
- do {
|
||||
- /* for retry wait for 1 ms till bus get settled down */
|
||||
- if (retry)
|
||||
- usleep_range(1000, 2000);
|
||||
|
||||
- ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
|
||||
- data, true);
|
||||
-
|
||||
- } while (ret != 0 && ret != -ENOMEDIUM &&
|
||||
- retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
|
||||
+ if ((addr & ~REG_F0_REG_MASK) == 0) {
|
||||
+ if (WARN_ON(regsz > 1))
|
||||
+ return -EINVAL;
|
||||
+ ret = brcmf_sdiod_f0_writeb(sdiodev->func[0],
|
||||
+ *(u8 *)data, addr);
|
||||
+ } else {
|
||||
+ switch (regsz) {
|
||||
+ case 1:
|
||||
+ sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ ret = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ if (ret)
|
||||
+ goto done;
|
||||
|
||||
- if (ret == -ENOMEDIUM)
|
||||
- brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
+ sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret);
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN(1, "Invalid reg size\n");
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
u8 regsz, void *data)
|
||||
{
|
||||
- u8 func;
|
||||
- s32 retry = 0;
|
||||
int ret;
|
||||
|
||||
- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
- return -ENOMEDIUM;
|
||||
-
|
||||
/*
|
||||
* figure out how to read the register based on address range
|
||||
* 0x00 ~ 0x7FF: function 0 CCCR and FBR
|
||||
* 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
|
||||
* The rest: function 1 silicon backplane core registers
|
||||
+ * f0 reads must be bytewise
|
||||
*/
|
||||
- if ((addr & ~REG_F0_REG_MASK) == 0)
|
||||
- func = SDIO_FUNC_0;
|
||||
- else
|
||||
- func = SDIO_FUNC_1;
|
||||
-
|
||||
- do {
|
||||
- memset(data, 0, regsz);
|
||||
-
|
||||
- /* for retry wait for 1 ms till bus get settled down */
|
||||
- if (retry)
|
||||
- usleep_range(1000, 2000);
|
||||
-
|
||||
- ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
|
||||
- data, false);
|
||||
-
|
||||
- } while (ret != 0 && ret != -ENOMEDIUM &&
|
||||
- retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
|
||||
-
|
||||
- if (ret == -ENOMEDIUM)
|
||||
- brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
|
||||
-{
|
||||
- int err = 0, i;
|
||||
- u32 addr;
|
||||
-
|
||||
- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
- return -ENOMEDIUM;
|
||||
-
|
||||
- addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
|
||||
-
|
||||
- for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
- addr & 0xff, &err);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
|
||||
-{
|
||||
- uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
- int err = 0;
|
||||
-
|
||||
- if (bar0 != sdiodev->sbwad) {
|
||||
- err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ if ((addr & ~REG_F0_REG_MASK) == 0) {
|
||||
+ if (WARN_ON(regsz > 1))
|
||||
+ return -EINVAL;
|
||||
+ *(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret);
|
||||
+ } else {
|
||||
+ switch (regsz) {
|
||||
+ case 1:
|
||||
+ *(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ ret = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ if (ret)
|
||||
+ goto done;
|
||||
|
||||
- sdiodev->sbwad = bar0;
|
||||
+ *(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret);
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN(1, "Invalid reg size\n");
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- *addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
-
|
||||
- return 0;
|
||||
+done:
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
@@ -439,15 +387,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
- if (retval)
|
||||
- goto done;
|
||||
-
|
||||
retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data);
|
||||
-
|
||||
brcmf_dbg(SDIO, "data:0x%08x\n", data);
|
||||
|
||||
-done:
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
|
||||
@@ -472,13 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
- if (retval)
|
||||
- goto done;
|
||||
-
|
||||
retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data);
|
||||
|
||||
-done:
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
}
|
||||
@@ -886,14 +823,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
return bcmerror;
|
||||
}
|
||||
|
||||
-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
|
||||
+int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
|
||||
{
|
||||
- char t_func = (char)fn;
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
/* issue abort cmd52 command through F0 */
|
||||
- brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
|
||||
- 1, &t_func, true);
|
||||
+ brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn);
|
||||
|
||||
brcmf_dbg(SDIO, "Exit\n");
|
||||
return 0;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -339,7 +339,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_
|
||||
u8 *data, uint size);
|
||||
|
||||
/* Issue an abort to the specified function */
|
||||
-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
|
||||
+int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn);
|
||||
void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev);
|
||||
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
|
||||
enum brcmf_sdiod_state state);
|
|
@ -0,0 +1,28 @@
|
|||
From 3508a056a1f45d95c874fc9af8748bf4229432b6 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:45 +0100
|
||||
Subject: [PATCH] brcmfmac: Fix asymmetric IO functions.
|
||||
|
||||
Unlikely to be a problem, but brcmf_sdiod_regrl() is
|
||||
not symmetric with brcmf_sdiod_regrb() in initializing
|
||||
the data value on stack. Fix that.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
[arend: reword the commit message a bit]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -383,7 +383,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
|
||||
|
||||
u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
{
|
||||
- u32 data = 0;
|
||||
+ u32 data;
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
|
@ -0,0 +1,53 @@
|
|||
From 12e3e74e2820e11d91ee44fd3a190cd80d109faa Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:46 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove noisy debugging.
|
||||
|
||||
If you need debugging this low level, you're doing something wrong.
|
||||
Remove these noisy debug statements so the code is more readable.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -371,9 +371,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
|
||||
u8 data;
|
||||
int retval;
|
||||
|
||||
- brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data);
|
||||
- brcmf_dbg(SDIO, "data:0x%02x\n", data);
|
||||
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
@@ -386,9 +384,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
u32 data;
|
||||
int retval;
|
||||
|
||||
- brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data);
|
||||
- brcmf_dbg(SDIO, "data:0x%08x\n", data);
|
||||
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
@@ -401,7 +397,6 @@ void brcmf_sdiod_regwb(struct brcmf_sdio
|
||||
{
|
||||
int retval;
|
||||
|
||||
- brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
|
||||
retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data);
|
||||
|
||||
if (ret)
|
||||
@@ -413,7 +408,6 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
{
|
||||
int retval;
|
||||
|
||||
- brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
|
||||
retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data);
|
||||
|
||||
if (ret)
|
|
@ -0,0 +1,58 @@
|
|||
From dd8a2d49e4ed321ab8e7b679499c3a98ccc5ca24 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Mon, 13 Nov 2017 21:35:47 +0100
|
||||
Subject: [PATCH] brcmfmac: Rename bcmerror to err
|
||||
|
||||
Trivial cleanup of nasty variable name
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -746,7 +746,7 @@ int
|
||||
brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
|
||||
u8 *data, uint size)
|
||||
{
|
||||
- int bcmerror = 0;
|
||||
+ int err = 0;
|
||||
struct sk_buff *pkt;
|
||||
u32 sdaddr;
|
||||
uint dsize;
|
||||
@@ -771,8 +771,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
/* Do the transfer(s) */
|
||||
while (size) {
|
||||
/* Set the backplane window to include the start address */
|
||||
- bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
|
||||
- if (bcmerror)
|
||||
+ err = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
|
||||
+ if (err)
|
||||
break;
|
||||
|
||||
brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
|
||||
@@ -785,9 +785,9 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
skb_put(pkt, dsize);
|
||||
if (write)
|
||||
memcpy(pkt->data, data, dsize);
|
||||
- bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
|
||||
- sdaddr, pkt);
|
||||
- if (bcmerror) {
|
||||
+ err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr,
|
||||
+ pkt);
|
||||
+ if (err) {
|
||||
brcmf_err("membytes transfer failed\n");
|
||||
break;
|
||||
}
|
||||
@@ -814,7 +814,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
- return bcmerror;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
|
|
@ -0,0 +1,143 @@
|
|||
From 8f13c87ccc495e30de5f58bbda967f6edd5bec53 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:26 +0100
|
||||
Subject: [PATCH] brcmfmac: Split brcmf_sdiod_buffrw function up.
|
||||
|
||||
This function needs to be split up into separate read / write variants
|
||||
for clarity.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 67 +++++++++++++++-------
|
||||
1 file changed, 45 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -414,8 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
|
||||
*ret = retval;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
- bool write, u32 addr, struct sk_buff *pkt)
|
||||
+static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
+ u32 addr, struct sk_buff *pkt)
|
||||
{
|
||||
unsigned int req_sz;
|
||||
int err;
|
||||
@@ -424,18 +424,36 @@ static int brcmf_sdiod_buffrw(struct brc
|
||||
req_sz = pkt->len + 3;
|
||||
req_sz &= (uint)~3;
|
||||
|
||||
- if (write)
|
||||
- err = sdio_memcpy_toio(sdiodev->func[fn], addr,
|
||||
- ((u8 *)(pkt->data)), req_sz);
|
||||
- else if (fn == 1)
|
||||
- err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
|
||||
- addr, req_sz);
|
||||
+ if (fn == 1)
|
||||
+ err = sdio_memcpy_fromio(sdiodev->func[fn],
|
||||
+ ((u8 *)(pkt->data)), addr, req_sz);
|
||||
else
|
||||
/* function 2 read is FIFO operation */
|
||||
- err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
|
||||
- req_sz);
|
||||
+ err = sdio_readsb(sdiodev->func[fn],
|
||||
+ ((u8 *)(pkt->data)), addr, req_sz);
|
||||
+
|
||||
+ if (err == -ENOMEDIUM)
|
||||
+ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
+ u32 addr, struct sk_buff *pkt)
|
||||
+{
|
||||
+ unsigned int req_sz;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Single skb use the standard mmc interface */
|
||||
+ req_sz = pkt->len + 3;
|
||||
+ req_sz &= (uint)~3;
|
||||
+
|
||||
+ err = sdio_memcpy_toio(sdiodev->func[fn], addr,
|
||||
+ ((u8 *)(pkt->data)), req_sz);
|
||||
+
|
||||
if (err == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -643,7 +661,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt);
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
|
||||
|
||||
done:
|
||||
return err;
|
||||
@@ -665,14 +683,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
goto done;
|
||||
|
||||
if (pktq->qlen == 1)
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
|
||||
- pktq->next);
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
|
||||
+ pktq->next);
|
||||
else if (!sdiodev->sg_support) {
|
||||
glom_skb = brcmu_pkt_buf_get_skb(totlen);
|
||||
if (!glom_skb)
|
||||
return -ENOMEM;
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
|
||||
- glom_skb);
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
|
||||
+ glom_skb);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
@@ -707,8 +725,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
|
||||
if (!err)
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
|
||||
- mypkt);
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
return err;
|
||||
@@ -730,8 +747,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
|
||||
if (pktq->qlen == 1 || !sdiodev->sg_support)
|
||||
skb_queue_walk(pktq, skb) {
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true,
|
||||
- addr, skb);
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
|
||||
+ addr, skb);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -783,10 +800,16 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
skb_put(pkt, dsize);
|
||||
- if (write)
|
||||
+
|
||||
+ if (write) {
|
||||
memcpy(pkt->data, data, dsize);
|
||||
- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr,
|
||||
- pkt);
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1,
|
||||
+ sdaddr, pkt);
|
||||
+ } else {
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1,
|
||||
+ sdaddr, pkt);
|
||||
+ }
|
||||
+
|
||||
if (err) {
|
||||
brcmf_err("membytes transfer failed\n");
|
||||
break;
|
|
@ -0,0 +1,34 @@
|
|||
From 6e24dd012bfda479d0046f7995058f167e1923bc Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:27 +0100
|
||||
Subject: [PATCH] brcmfmac: whitespace fixes in brcmf_sdiod_send_buf()
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: mention function in patch subject]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -714,6 +714,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
int err;
|
||||
|
||||
mypkt = brcmu_pkt_buf_get_skb(nbytes);
|
||||
+
|
||||
if (!mypkt) {
|
||||
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
|
||||
nbytes);
|
||||
@@ -728,8 +729,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
- return err;
|
||||
|
||||
+ return err;
|
||||
}
|
||||
|
||||
int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
|
|
@ -0,0 +1,36 @@
|
|||
From a7323378dcf1f10a98f47b744e6f65e6fd671d84 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:28 +0100
|
||||
Subject: [PATCH] brcmfmac: Clarify if using braces.
|
||||
|
||||
Whilst this if () statement is technically correct, it lacks clarity.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -746,16 +746,17 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (pktq->qlen == 1 || !sdiodev->sg_support)
|
||||
+ if (pktq->qlen == 1 || !sdiodev->sg_support) {
|
||||
skb_queue_walk(pktq, skb) {
|
||||
err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
|
||||
addr, skb);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
- else
|
||||
+ } else {
|
||||
err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
|
||||
pktq);
|
||||
+ }
|
||||
|
||||
return err;
|
||||
}
|
|
@ -0,0 +1,831 @@
|
|||
From 71bd508d7ded8c504ef05d1b4befecfe25e54cb1 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:29 +0100
|
||||
Subject: [PATCH] brcmfmac: Rename / replace old IO functions with simpler
|
||||
ones.
|
||||
|
||||
Primarily this patch removes:
|
||||
|
||||
brcmf_sdiod_f0_writeb()
|
||||
brcmf_sdiod_reg_write()
|
||||
brcmf_sdiod_reg_read()
|
||||
|
||||
Since we no longer use the quirky method of deciding which function to
|
||||
address via the address being accessed, take the opportunity to rename
|
||||
some IO functions more in line with common kernel code. We also convert
|
||||
those that map directly to sdio_{read,write}*() to macros.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 169 +++----------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 186 ++++++++++-----------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 28 +++-
|
||||
3 files changed, 138 insertions(+), 245 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -137,27 +137,27 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
|
||||
/* assign GPIO to SDIO core */
|
||||
addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
|
||||
- gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
|
||||
+ gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret);
|
||||
gpiocontrol |= 0x2;
|
||||
- brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
|
||||
+ brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret);
|
||||
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
|
||||
- &ret);
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT,
|
||||
+ 0xf, &ret);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
|
||||
}
|
||||
|
||||
/* must configure SDIO_CCCR_IENx to enable irq */
|
||||
- data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
|
||||
+ data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);
|
||||
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
|
||||
- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
|
||||
|
||||
/* redirect, configure and enable io for interrupt signal */
|
||||
data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
|
||||
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
|
||||
data |= SDIO_SEPINT_ACT_HI;
|
||||
- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
|
||||
-
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,
|
||||
+ data, &ret);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
} else {
|
||||
brcmf_dbg(SDIO, "Entering\n");
|
||||
@@ -183,8 +183,8 @@ void brcmf_sdiod_intr_unregister(struct
|
||||
|
||||
pdata = &sdiodev->settings->bus.sdio;
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
|
||||
- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
sdiodev->oob_irq_requested = false;
|
||||
@@ -242,8 +242,8 @@ static int brcmf_sdiod_set_sbaddr_window
|
||||
addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
|
||||
|
||||
for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
- addr & 0xff, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
+ addr & 0xff, &err);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -267,124 +267,15 @@ static int brcmf_sdiod_addrprep(struct b
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
|
||||
- uint regaddr)
|
||||
-{
|
||||
- int err_ret;
|
||||
-
|
||||
- /*
|
||||
- * Can only directly write to some F0 registers.
|
||||
- * Handle CCCR_IENx and CCCR_ABORT command
|
||||
- * as a special case.
|
||||
- */
|
||||
- if ((regaddr == SDIO_CCCR_ABORT) ||
|
||||
- (regaddr == SDIO_CCCR_IENx))
|
||||
- sdio_writeb(func, byte, regaddr, &err_ret);
|
||||
- else
|
||||
- sdio_f0_writeb(func, byte, regaddr, &err_ret);
|
||||
-
|
||||
- return err_ret;
|
||||
-}
|
||||
-
|
||||
-static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
- u8 regsz, void *data)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * figure out how to read the register based on address range
|
||||
- * 0x00 ~ 0x7FF: function 0 CCCR and FBR
|
||||
- * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
|
||||
- * The rest: function 1 silicon backplane core registers
|
||||
- * f0 writes must be bytewise
|
||||
- */
|
||||
-
|
||||
- if ((addr & ~REG_F0_REG_MASK) == 0) {
|
||||
- if (WARN_ON(regsz > 1))
|
||||
- return -EINVAL;
|
||||
- ret = brcmf_sdiod_f0_writeb(sdiodev->func[0],
|
||||
- *(u8 *)data, addr);
|
||||
- } else {
|
||||
- switch (regsz) {
|
||||
- case 1:
|
||||
- sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret);
|
||||
- break;
|
||||
- case 4:
|
||||
- ret = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
- if (ret)
|
||||
- goto done;
|
||||
-
|
||||
- sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret);
|
||||
- break;
|
||||
- default:
|
||||
- WARN(1, "Invalid reg size\n");
|
||||
- ret = -EINVAL;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-done:
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
- u8 regsz, void *data)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * figure out how to read the register based on address range
|
||||
- * 0x00 ~ 0x7FF: function 0 CCCR and FBR
|
||||
- * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
|
||||
- * The rest: function 1 silicon backplane core registers
|
||||
- * f0 reads must be bytewise
|
||||
- */
|
||||
- if ((addr & ~REG_F0_REG_MASK) == 0) {
|
||||
- if (WARN_ON(regsz > 1))
|
||||
- return -EINVAL;
|
||||
- *(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret);
|
||||
- } else {
|
||||
- switch (regsz) {
|
||||
- case 1:
|
||||
- *(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret);
|
||||
- break;
|
||||
- case 4:
|
||||
- ret = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
- if (ret)
|
||||
- goto done;
|
||||
-
|
||||
- *(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret);
|
||||
- break;
|
||||
- default:
|
||||
- WARN(1, "Invalid reg size\n");
|
||||
- ret = -EINVAL;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-done:
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
+u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
{
|
||||
- u8 data;
|
||||
+ u32 data = 0;
|
||||
int retval;
|
||||
|
||||
- retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data);
|
||||
-
|
||||
- if (ret)
|
||||
- *ret = retval;
|
||||
-
|
||||
- return data;
|
||||
-}
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
|
||||
-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
-{
|
||||
- u32 data;
|
||||
- int retval;
|
||||
-
|
||||
- retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data);
|
||||
+ if (!retval)
|
||||
+ data = sdio_readl(sdiodev->func[1], addr, &retval);
|
||||
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
@@ -392,23 +283,15 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
|
||||
return data;
|
||||
}
|
||||
|
||||
-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
- u8 data, int *ret)
|
||||
+void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
+ u32 data, int *ret)
|
||||
{
|
||||
int retval;
|
||||
|
||||
- retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data);
|
||||
-
|
||||
- if (ret)
|
||||
- *ret = retval;
|
||||
-}
|
||||
-
|
||||
-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
|
||||
- u32 data, int *ret)
|
||||
-{
|
||||
- int retval;
|
||||
+ retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
|
||||
- retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data);
|
||||
+ if (!retval)
|
||||
+ sdio_writel(sdiodev->func[1], data, addr, &retval);
|
||||
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
@@ -846,8 +729,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_
|
||||
{
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
- /* issue abort cmd52 command through F0 */
|
||||
- brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn);
|
||||
+ /* Issue abort cmd52 command through F0 */
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL);
|
||||
|
||||
brcmf_dbg(SDIO, "Exit\n");
|
||||
return 0;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -669,7 +669,7 @@ static int r_sdreg32(struct brcmf_sdio *
|
||||
int ret;
|
||||
|
||||
core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
- *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
|
||||
+ *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -680,7 +680,7 @@ static int w_sdreg32(struct brcmf_sdio *
|
||||
int ret;
|
||||
|
||||
core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
- brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
|
||||
+ brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -697,8 +697,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
|
||||
|
||||
wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
|
||||
/* 1st KSO write goes to AOS wake up core if device is asleep */
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
- wr_val, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
|
||||
|
||||
if (on) {
|
||||
/* device WAKEUP through KSO:
|
||||
@@ -724,7 +723,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
|
||||
* just one write attempt may fail,
|
||||
* read it back until it matches written value
|
||||
*/
|
||||
- rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
+ rd_val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
&err);
|
||||
if (!err) {
|
||||
if ((rd_val & bmask) == cmp_val)
|
||||
@@ -734,9 +733,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio
|
||||
/* bail out upon subsequent access errors */
|
||||
if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS))
|
||||
break;
|
||||
+
|
||||
udelay(KSO_WAIT_US);
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
- wr_val, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val,
|
||||
+ &err);
|
||||
+
|
||||
} while (try_cnt++ < MAX_KSO_ATTEMPTS);
|
||||
|
||||
if (try_cnt > 2)
|
||||
@@ -772,15 +773,15 @@ static int brcmf_sdio_htclk(struct brcmf
|
||||
clkreq =
|
||||
bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
|
||||
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- clkreq, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ clkreq, &err);
|
||||
if (err) {
|
||||
brcmf_err("HT Avail request error: %d\n", err);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
/* Check current status */
|
||||
- clkctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ clkctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
if (err) {
|
||||
brcmf_err("HT Avail read error: %d\n", err);
|
||||
@@ -790,35 +791,34 @@ static int brcmf_sdio_htclk(struct brcmf
|
||||
/* Go to pending and await interrupt if appropriate */
|
||||
if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
|
||||
/* Allow only clock-available interrupt */
|
||||
- devctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ devctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_DEVICE_CTL, &err);
|
||||
if (err) {
|
||||
- brcmf_err("Devctl error setting CA: %d\n",
|
||||
- err);
|
||||
+ brcmf_err("Devctl error setting CA: %d\n", err);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
- devctl, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
+ devctl, &err);
|
||||
brcmf_dbg(SDIO, "CLKCTL: set PENDING\n");
|
||||
bus->clkstate = CLK_PENDING;
|
||||
|
||||
return 0;
|
||||
} else if (bus->clkstate == CLK_PENDING) {
|
||||
/* Cancel CA-only interrupt filter */
|
||||
- devctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ devctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_DEVICE_CTL, &err);
|
||||
devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
- devctl, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
+ devctl, &err);
|
||||
}
|
||||
|
||||
/* Otherwise, wait here (polling) for HT Avail */
|
||||
timeout = jiffies +
|
||||
msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
|
||||
while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
|
||||
- clkctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ clkctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
&err);
|
||||
if (time_after(jiffies, timeout))
|
||||
@@ -852,16 +852,16 @@ static int brcmf_sdio_htclk(struct brcmf
|
||||
|
||||
if (bus->clkstate == CLK_PENDING) {
|
||||
/* Cancel CA-only interrupt filter */
|
||||
- devctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ devctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_DEVICE_CTL, &err);
|
||||
devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
- devctl, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
+ devctl, &err);
|
||||
}
|
||||
|
||||
bus->clkstate = CLK_SDONLY;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- clkreq, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ clkreq, &err);
|
||||
brcmf_dbg(SDIO, "CLKCTL: turned OFF\n");
|
||||
if (err) {
|
||||
brcmf_err("Failed access turning clock off: %d\n",
|
||||
@@ -951,14 +951,14 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
|
||||
|
||||
/* Going to sleep */
|
||||
if (sleep) {
|
||||
- clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ clkcsr = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
&err);
|
||||
if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
|
||||
brcmf_dbg(SDIO, "no clock, set ALP\n");
|
||||
- brcmf_sdiod_regwb(bus->sdiodev,
|
||||
- SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- SBSDIO_ALP_AVAIL_REQ, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev,
|
||||
+ SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ SBSDIO_ALP_AVAIL_REQ, &err);
|
||||
}
|
||||
err = brcmf_sdio_kso_control(bus, false);
|
||||
} else {
|
||||
@@ -1178,16 +1178,16 @@ static void brcmf_sdio_rxfail(struct brc
|
||||
if (abort)
|
||||
brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
|
||||
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
|
||||
- SFC_RF_TERM, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
|
||||
+ &err);
|
||||
bus->sdcnt.f1regdata++;
|
||||
|
||||
/* Wait until the packet has been flushed (device/FIFO stable) */
|
||||
for (lastrbc = retries = 0xffff; retries > 0; retries--) {
|
||||
- hi = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
- SBSDIO_FUNC1_RFRAMEBCHI, &err);
|
||||
- lo = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
- SBSDIO_FUNC1_RFRAMEBCLO, &err);
|
||||
+ hi = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI,
|
||||
+ &err);
|
||||
+ lo = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO,
|
||||
+ &err);
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
|
||||
if ((hi == 0) && (lo == 0))
|
||||
@@ -1229,12 +1229,12 @@ static void brcmf_sdio_txfail(struct brc
|
||||
bus->sdcnt.tx_sderrs++;
|
||||
|
||||
brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
|
||||
bus->sdcnt.f1regdata++;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
- hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
|
||||
- lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
|
||||
+ hi = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
|
||||
+ lo = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
if ((hi == 0) && (lo == 0))
|
||||
break;
|
||||
@@ -2446,11 +2446,11 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
bus->hostintmask = 0;
|
||||
|
||||
/* Force backplane clocks to assure F2 interrupt propagates */
|
||||
- saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
&err);
|
||||
if (!err)
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- (saveclk | SBSDIO_FORCE_HT), &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ (saveclk | SBSDIO_FORCE_HT), &err);
|
||||
if (err)
|
||||
brcmf_err("Failed to force clock for F2: err %d\n",
|
||||
err);
|
||||
@@ -2509,7 +2509,7 @@ static int brcmf_sdio_intr_rstatus(struc
|
||||
buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
|
||||
|
||||
- val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
|
||||
+ val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
|
||||
bus->sdcnt.f1regdata++;
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@@ -2519,7 +2519,7 @@ static int brcmf_sdio_intr_rstatus(struc
|
||||
|
||||
/* Clear interrupts */
|
||||
if (val) {
|
||||
- brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
|
||||
+ brcmf_sdiod_writel(bus->sdiodev, addr, val, &ret);
|
||||
bus->sdcnt.f1regdata++;
|
||||
atomic_or(val, &bus->intstatus);
|
||||
}
|
||||
@@ -2545,23 +2545,23 @@ static void brcmf_sdio_dpc(struct brcmf_
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Check for inconsistent device control */
|
||||
- devctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
- SBSDIO_DEVICE_CTL, &err);
|
||||
+ devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
+ &err);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* Read CSR, if clock on switch to AVAIL, else ignore */
|
||||
- clkctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ clkctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
|
||||
brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
|
||||
devctl, clkctl);
|
||||
|
||||
if (SBSDIO_HTAV(clkctl)) {
|
||||
- devctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ devctl = brcmf_sdiod_readb(bus->sdiodev,
|
||||
SBSDIO_DEVICE_CTL, &err);
|
||||
devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
|
||||
- devctl, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev,
|
||||
+ SBSDIO_DEVICE_CTL, devctl, &err);
|
||||
bus->clkstate = CLK_AVAIL;
|
||||
}
|
||||
}
|
||||
@@ -3347,31 +3347,31 @@ static void brcmf_sdio_sr_init(struct br
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
- val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
|
||||
+ val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
|
||||
if (err) {
|
||||
brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add CMD14 Support */
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
|
||||
- (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
|
||||
- SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
|
||||
- &err);
|
||||
+ brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
|
||||
+ (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
|
||||
+ SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
|
||||
+ &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
|
||||
return;
|
||||
}
|
||||
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- SBSDIO_FORCE_HT, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ SBSDIO_FORCE_HT, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
|
||||
return;
|
||||
@@ -3394,7 +3394,7 @@ static int brcmf_sdio_kso_init(struct br
|
||||
if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
|
||||
return 0;
|
||||
|
||||
- val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
|
||||
+ val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
|
||||
if (err) {
|
||||
brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n");
|
||||
return err;
|
||||
@@ -3403,8 +3403,8 @@ static int brcmf_sdio_kso_init(struct br
|
||||
if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
|
||||
val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN <<
|
||||
SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
- val, &err);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
+ val, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n");
|
||||
return err;
|
||||
@@ -3565,9 +3565,9 @@ static void brcmf_sdio_bus_watchdog(stru
|
||||
u8 devpend;
|
||||
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
- devpend = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
- SDIO_CCCR_INTx,
|
||||
- NULL);
|
||||
+ devpend = brcmf_sdiod_func0_rb(bus->sdiodev,
|
||||
+ SDIO_CCCR_INTx,
|
||||
+ NULL);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
intstatus = devpend & (INTR_STATUS_FUNC1 |
|
||||
INTR_STATUS_FUNC2);
|
||||
@@ -3705,12 +3705,12 @@ brcmf_sdio_drivestrengthinit(struct brcm
|
||||
}
|
||||
}
|
||||
addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
|
||||
- brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
|
||||
- cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
|
||||
+ brcmf_sdiod_writel(sdiodev, addr, 1, NULL);
|
||||
+ cc_data_temp = brcmf_sdiod_readl(sdiodev, addr, NULL);
|
||||
cc_data_temp &= ~str_mask;
|
||||
drivestrength_sel <<= str_shift;
|
||||
cc_data_temp |= drivestrength_sel;
|
||||
- brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
|
||||
+ brcmf_sdiod_writel(sdiodev, addr, cc_data_temp, NULL);
|
||||
|
||||
brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
|
||||
str_tab[i].strength, drivestrength, cc_data_temp);
|
||||
@@ -3725,7 +3725,7 @@ static int brcmf_sdio_buscoreprep(void *
|
||||
|
||||
/* Try forcing SDIO core to do ALPAvail request only */
|
||||
clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
|
||||
if (err) {
|
||||
brcmf_err("error writing for HT off\n");
|
||||
return err;
|
||||
@@ -3733,8 +3733,7 @@ static int brcmf_sdio_buscoreprep(void *
|
||||
|
||||
/* If register supported, wait for ALPAvail and then force ALP */
|
||||
/* This may take up to 15 milliseconds */
|
||||
- clkval = brcmf_sdiod_regrb(sdiodev,
|
||||
- SBSDIO_FUNC1_CHIPCLKCSR, NULL);
|
||||
+ clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
|
||||
|
||||
if ((clkval & ~SBSDIO_AVBITS) != clkset) {
|
||||
brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
|
||||
@@ -3742,10 +3741,11 @@ static int brcmf_sdio_buscoreprep(void *
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
- SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
|
||||
- SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
|
||||
- !SBSDIO_ALPAV(clkval)),
|
||||
- PMU_MAX_TRANSITION_DLY);
|
||||
+ SPINWAIT(((clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ NULL)),
|
||||
+ !SBSDIO_ALPAV(clkval)),
|
||||
+ PMU_MAX_TRANSITION_DLY);
|
||||
+
|
||||
if (!SBSDIO_ALPAV(clkval)) {
|
||||
brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
|
||||
clkval);
|
||||
@@ -3753,11 +3753,11 @@ static int brcmf_sdio_buscoreprep(void *
|
||||
}
|
||||
|
||||
clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
|
||||
udelay(65);
|
||||
|
||||
/* Also, disable the extra SDIO pull-ups */
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3772,7 +3772,7 @@ static void brcmf_sdio_buscore_activate(
|
||||
/* clear all interrupts */
|
||||
core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
|
||||
reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
|
||||
- brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
|
||||
+ brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
|
||||
|
||||
if (rstvec)
|
||||
/* Write reset vector to address 0 */
|
||||
@@ -3785,7 +3785,7 @@ static u32 brcmf_sdio_buscore_read32(voi
|
||||
struct brcmf_sdio_dev *sdiodev = ctx;
|
||||
u32 val, rev;
|
||||
|
||||
- val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
|
||||
+ val = brcmf_sdiod_readl(sdiodev, addr, NULL);
|
||||
if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
|
||||
sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
|
||||
addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
@@ -3802,7 +3802,7 @@ static void brcmf_sdio_buscore_write32(v
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev = ctx;
|
||||
|
||||
- brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
|
||||
+ brcmf_sdiod_writel(sdiodev, addr, val, NULL);
|
||||
}
|
||||
|
||||
static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
|
||||
@@ -3826,18 +3826,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
|
||||
pr_debug("F1 signature read @0x18000000=0x%4x\n",
|
||||
- brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL));
|
||||
+ brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL));
|
||||
|
||||
/*
|
||||
* Force PLL off until brcmf_chip_attach()
|
||||
* programs PLL control regs
|
||||
*/
|
||||
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- BRCMF_INIT_CLKCTL1, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1,
|
||||
+ &err);
|
||||
if (!err)
|
||||
- clkctl = brcmf_sdiod_regrb(sdiodev,
|
||||
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
+ clkctl = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ &err);
|
||||
|
||||
if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
|
||||
brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
|
||||
@@ -3897,25 +3897,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);
|
||||
|
||||
/* Set card control so an SDIO card reset does a WLAN backplane reset */
|
||||
- reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
|
||||
+ reg_val = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
|
||||
|
||||
- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* set PMUControl so a backplane reset does PMU state reload */
|
||||
reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
|
||||
- reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err);
|
||||
+ reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
|
||||
|
||||
- brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err);
|
||||
+ brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
@@ -4055,10 +4055,10 @@ static void brcmf_sdio_firmware_callback
|
||||
goto release;
|
||||
|
||||
/* Force clocks on backplane to be sure F2 interrupt propagates */
|
||||
- saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
+ saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
if (!err) {
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- (saveclk | SBSDIO_FORCE_HT), &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ (saveclk | SBSDIO_FORCE_HT), &err);
|
||||
}
|
||||
if (err) {
|
||||
brcmf_err("Failed to force clock for F2: err %d\n", err);
|
||||
@@ -4080,7 +4080,7 @@ static void brcmf_sdio_firmware_callback
|
||||
w_sdreg32(bus, bus->hostintmask,
|
||||
offsetof(struct sdpcmd_regs, hostintmask));
|
||||
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
} else {
|
||||
/* Disable F2 again */
|
||||
sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
@@ -4091,8 +4091,8 @@ static void brcmf_sdio_firmware_callback
|
||||
brcmf_sdio_sr_init(bus);
|
||||
} else {
|
||||
/* Restore previous clock setting */
|
||||
- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
- saveclk, &err);
|
||||
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ saveclk, &err);
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
@@ -4225,7 +4225,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
|
||||
bus->rxflow = false;
|
||||
|
||||
/* Done with backplane-dependent accesses, can drop clock... */
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
|
||||
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
|
||||
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -50,6 +50,7 @@
|
||||
#define SBSDIO_NUM_FUNCTION 3
|
||||
|
||||
/* function 0 vendor specific CCCR registers */
|
||||
+
|
||||
#define SDIO_CCCR_BRCM_CARDCAP 0xf0
|
||||
#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02
|
||||
#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04
|
||||
@@ -131,8 +132,6 @@
|
||||
/* with b15, maps to 32-bit SB access */
|
||||
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000
|
||||
|
||||
-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
|
||||
-
|
||||
/* Address bits from SBADDR regs */
|
||||
#define SBSDIO_SBWINDOW_MASK 0xffff8000
|
||||
|
||||
@@ -293,13 +292,24 @@ struct sdpcmd_regs {
|
||||
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
|
||||
void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
-/* sdio device register access interface */
|
||||
-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
|
||||
-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
|
||||
-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data,
|
||||
- int *ret);
|
||||
-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data,
|
||||
- int *ret);
|
||||
+/* SDIO device register access interface */
|
||||
+/* Accessors for SDIO Function 0 */
|
||||
+#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
|
||||
+ sdio_readb((sdiodev)->func[0], (addr), (r))
|
||||
+
|
||||
+#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
|
||||
+ sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
|
||||
+
|
||||
+/* Accessors for SDIO Function 1 */
|
||||
+#define brcmf_sdiod_readb(sdiodev, addr, r) \
|
||||
+ sdio_readb((sdiodev)->func[1], (addr), (r))
|
||||
+
|
||||
+#define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \
|
||||
+ sdio_writeb((sdiodev)->func[1], (v), (addr), (ret))
|
||||
+
|
||||
+u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
|
||||
+void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data,
|
||||
+ int *ret);
|
||||
|
||||
/* Buffer transfer to/from device (client) core via cmd53.
|
||||
* fn: function number
|
|
@ -0,0 +1,59 @@
|
|||
From eeef8a5da781e11746347b3cd9f1942be48ebaf0 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:30 +0100
|
||||
Subject: [PATCH] brcmfmac: Tidy register definitions a little
|
||||
|
||||
Trivial tidy of register definitions.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++--
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 19 ++++++++++---------
|
||||
2 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -153,9 +153,9 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
|
||||
|
||||
/* redirect, configure and enable io for interrupt signal */
|
||||
- data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
|
||||
+ data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE;
|
||||
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
|
||||
- data |= SDIO_SEPINT_ACT_HI;
|
||||
+ data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
|
||||
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,
|
||||
data, &ret);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -52,16 +52,17 @@
|
||||
/* function 0 vendor specific CCCR registers */
|
||||
|
||||
#define SDIO_CCCR_BRCM_CARDCAP 0xf0
|
||||
-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02
|
||||
-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04
|
||||
-#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08
|
||||
-#define SDIO_CCCR_BRCM_CARDCTRL 0xf1
|
||||
-#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02
|
||||
-#define SDIO_CCCR_BRCM_SEPINT 0xf2
|
||||
+#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT BIT(1)
|
||||
+#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2)
|
||||
+#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3)
|
||||
+
|
||||
+#define SDIO_CCCR_BRCM_CARDCTRL 0xf1
|
||||
+#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET BIT(1)
|
||||
|
||||
-#define SDIO_SEPINT_MASK 0x01
|
||||
-#define SDIO_SEPINT_OE 0x02
|
||||
-#define SDIO_SEPINT_ACT_HI 0x04
|
||||
+#define SDIO_CCCR_BRCM_SEPINT 0xf2
|
||||
+#define SDIO_CCCR_BRCM_SEPINT_MASK BIT(0)
|
||||
+#define SDIO_CCCR_BRCM_SEPINT_OE BIT(1)
|
||||
+#define SDIO_CCCR_BRCM_SEPINT_ACT_HI BIT(2)
|
||||
|
||||
/* function 1 miscellaneous registers */
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
From a7c3aa1509e243a09c5b1660c8702d792ca76aed Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:31 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_addrprep()
|
||||
|
||||
This function has become trivial enough that it may as well be pushed into
|
||||
its callers, which has the side-benefit of clarifying what's going on.
|
||||
|
||||
Remove it, and rename brcmf_sdiod_set_sbaddr_window() to
|
||||
brcmf_sdiod_set_backplane_window() as it's easier to understand.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 84 ++++++++++++----------
|
||||
1 file changed, 46 insertions(+), 38 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -230,41 +230,25 @@ void brcmf_sdiod_change_state(struct brc
|
||||
sdiodev->state = state;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
|
||||
- u32 address)
|
||||
+static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev,
|
||||
+ u32 addr)
|
||||
{
|
||||
+ u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK;
|
||||
int err = 0, i;
|
||||
- u32 addr;
|
||||
|
||||
- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
|
||||
- return -ENOMEDIUM;
|
||||
+ if (bar0 == sdiodev->sbwad)
|
||||
+ return 0;
|
||||
|
||||
- addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
|
||||
+ v = bar0 >> 8;
|
||||
|
||||
- for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
|
||||
+ for (i = 0 ; i < 3 && !err ; i++, v >>= 8)
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
|
||||
- addr & 0xff, &err);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
|
||||
-{
|
||||
- uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
- int err = 0;
|
||||
-
|
||||
- if (bar0 != sdiodev->sbwad) {
|
||||
- err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ v & 0xff, &err);
|
||||
|
||||
+ if (!err)
|
||||
sdiodev->sbwad = bar0;
|
||||
- }
|
||||
|
||||
- *addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
-
|
||||
- return 0;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
@@ -272,11 +256,16 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_
|
||||
u32 data = 0;
|
||||
int retval;
|
||||
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
+ if (retval)
|
||||
+ goto out;
|
||||
+
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
- if (!retval)
|
||||
- data = sdio_readl(sdiodev->func[1], addr, &retval);
|
||||
+ data = sdio_readl(sdiodev->func[1], addr, &retval);
|
||||
|
||||
+out:
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
|
||||
@@ -288,11 +277,16 @@ void brcmf_sdiod_writel(struct brcmf_sdi
|
||||
{
|
||||
int retval;
|
||||
|
||||
- retval = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
+ if (retval)
|
||||
+ goto out;
|
||||
|
||||
- if (!retval)
|
||||
- sdio_writel(sdiodev->func[1], data, addr, &retval);
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
+ sdio_writel(sdiodev->func[1], data, addr, &retval);
|
||||
+
|
||||
+out:
|
||||
if (ret)
|
||||
*ret = retval;
|
||||
}
|
||||
@@ -540,10 +534,13 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
+
|
||||
err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
|
||||
|
||||
done:
|
||||
@@ -561,10 +558,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
|
||||
addr, pktq->qlen);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
+
|
||||
if (pktq->qlen == 1)
|
||||
err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
|
||||
pktq->next);
|
||||
@@ -606,7 +606,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
|
||||
memcpy(mypkt->data, buf, nbytes);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
if (!err)
|
||||
err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
|
||||
@@ -625,10 +630,13 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
|
||||
|
||||
- err = brcmf_sdiod_addrprep(sdiodev, &addr);
|
||||
+ err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
+
|
||||
if (pktq->qlen == 1 || !sdiodev->sg_support) {
|
||||
skb_queue_walk(pktq, skb) {
|
||||
err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
|
||||
@@ -673,7 +681,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
/* Do the transfer(s) */
|
||||
while (size) {
|
||||
/* Set the backplane window to include the start address */
|
||||
- err = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
|
||||
+ err = brcmf_sdiod_set_backplane_window(sdiodev, address);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
@@ -716,7 +724,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
dev_kfree_skb(pkt);
|
||||
|
||||
/* Return the window to backplane enumeration space for core access */
|
||||
- if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad))
|
||||
+ if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad))
|
||||
brcmf_err("FAILED to set window back to 0x%x\n",
|
||||
sdiodev->sbwad);
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
From c900072bd6faff089aa4fb7b19136a2a0fe3baf0 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:32 +0100
|
||||
Subject: [PATCH] brcmfmac: remove unnecessary call to
|
||||
brcmf_sdiod_set_backplane_window()
|
||||
|
||||
All functions that might require the window address changing call
|
||||
brcmf_sdiod_set_backplane_window() prior to access. Thus resetting
|
||||
the window is not required.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
[arend: corrected the driver prefix in the subject]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -723,11 +723,6 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
|
||||
dev_kfree_skb(pkt);
|
||||
|
||||
- /* Return the window to backplane enumeration space for core access */
|
||||
- if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad))
|
||||
- brcmf_err("FAILED to set window back to 0x%x\n",
|
||||
- sdiodev->sbwad);
|
||||
-
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
return err;
|
|
@ -0,0 +1,134 @@
|
|||
From e4c05fc3c0a6c79376f72f17d08014477e962ada Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:33 +0100
|
||||
Subject: [PATCH] brcmfmac: Cleanup offsetof()
|
||||
|
||||
Create a macro to make the code a bit more readable, whilst we're stuck
|
||||
with using struct element offsets as register offsets.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: rename macro to SD_REG]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 35 +++++++++-------------
|
||||
1 file changed, 14 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -161,6 +161,8 @@ struct rte_console {
|
||||
|
||||
#define CORE_BUS_REG(base, field) \
|
||||
(base + offsetof(struct sdpcmd_regs, field))
|
||||
+#define SD_REG(field) \
|
||||
+ (offsetof(struct sdpcmd_regs, field))
|
||||
|
||||
/* SDIO function 1 register CHIPCLKCSR */
|
||||
/* Force ALP request to backplane */
|
||||
@@ -1087,12 +1089,10 @@ static u32 brcmf_sdio_hostmail(struct br
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
/* Read mailbox data and ack that we did so */
|
||||
- ret = r_sdreg32(bus, &hmb_data,
|
||||
- offsetof(struct sdpcmd_regs, tohostmailboxdata));
|
||||
+ ret = r_sdreg32(bus, &hmb_data, SD_REG(tohostmailboxdata));
|
||||
|
||||
if (ret == 0)
|
||||
- w_sdreg32(bus, SMB_INT_ACK,
|
||||
- offsetof(struct sdpcmd_regs, tosbmailbox));
|
||||
+ w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox));
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
|
||||
/* dongle indicates the firmware has halted/crashed */
|
||||
@@ -1207,8 +1207,7 @@ static void brcmf_sdio_rxfail(struct brc
|
||||
|
||||
if (rtx) {
|
||||
bus->sdcnt.rxrtx++;
|
||||
- err = w_sdreg32(bus, SMB_NAK,
|
||||
- offsetof(struct sdpcmd_regs, tosbmailbox));
|
||||
+ err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox));
|
||||
|
||||
bus->sdcnt.f1regdata++;
|
||||
if (err == 0)
|
||||
@@ -2333,9 +2332,7 @@ static uint brcmf_sdio_sendfromq(struct
|
||||
if (!bus->intr) {
|
||||
/* Check device status, signal pending interrupt */
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
- ret = r_sdreg32(bus, &intstatus,
|
||||
- offsetof(struct sdpcmd_regs,
|
||||
- intstatus));
|
||||
+ ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus));
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
bus->sdcnt.f2txdata++;
|
||||
if (ret != 0)
|
||||
@@ -2441,7 +2438,7 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
brcmf_sdio_bus_sleep(bus, false, false);
|
||||
|
||||
/* Disable and clear interrupts at the chip level also */
|
||||
- w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
|
||||
+ w_sdreg32(bus, 0, SD_REG(hostintmask));
|
||||
local_hostintmask = bus->hostintmask;
|
||||
bus->hostintmask = 0;
|
||||
|
||||
@@ -2460,8 +2457,7 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
/* Clear any pending interrupts now that F2 is disabled */
|
||||
- w_sdreg32(bus, local_hostintmask,
|
||||
- offsetof(struct sdpcmd_regs, intstatus));
|
||||
+ w_sdreg32(bus, local_hostintmask, SD_REG(intstatus));
|
||||
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
}
|
||||
@@ -2507,7 +2503,7 @@ static int brcmf_sdio_intr_rstatus(struc
|
||||
int ret;
|
||||
|
||||
buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
- addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
|
||||
+ addr = buscore->base + SD_REG(intstatus);
|
||||
|
||||
val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
|
||||
bus->sdcnt.f1regdata++;
|
||||
@@ -2584,11 +2580,9 @@ static void brcmf_sdio_dpc(struct brcmf_
|
||||
*/
|
||||
if (intstatus & I_HMB_FC_CHANGE) {
|
||||
intstatus &= ~I_HMB_FC_CHANGE;
|
||||
- err = w_sdreg32(bus, I_HMB_FC_CHANGE,
|
||||
- offsetof(struct sdpcmd_regs, intstatus));
|
||||
+ err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus));
|
||||
|
||||
- err = r_sdreg32(bus, &newstatus,
|
||||
- offsetof(struct sdpcmd_regs, intstatus));
|
||||
+ err = r_sdreg32(bus, &newstatus, SD_REG(intstatus));
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
atomic_set(&bus->fcstate,
|
||||
!!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
|
||||
@@ -3771,7 +3765,7 @@ static void brcmf_sdio_buscore_activate(
|
||||
|
||||
/* clear all interrupts */
|
||||
core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
|
||||
- reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
|
||||
+ reg_addr = core->base + SD_REG(intstatus);
|
||||
brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
|
||||
|
||||
if (rstvec)
|
||||
@@ -4067,7 +4061,7 @@ static void brcmf_sdio_firmware_callback
|
||||
|
||||
/* Enable function 2 (frame transfers) */
|
||||
w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
|
||||
- offsetof(struct sdpcmd_regs, tosbmailboxdata));
|
||||
+ SD_REG(tosbmailboxdata));
|
||||
err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
|
||||
@@ -4077,8 +4071,7 @@ static void brcmf_sdio_firmware_callback
|
||||
if (!err) {
|
||||
/* Set up the interrupt mask and enable interrupts */
|
||||
bus->hostintmask = HOSTINTMASK;
|
||||
- w_sdreg32(bus, bus->hostintmask,
|
||||
- offsetof(struct sdpcmd_regs, hostintmask));
|
||||
+ w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask));
|
||||
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
} else {
|
|
@ -0,0 +1,26 @@
|
|||
From 5cfe38f1f8d3c6b98e15b8cfde05028a3c79930b Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:34 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove unused macro.
|
||||
|
||||
This macro is used exactly nowhere in the code. Delete it.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -159,8 +159,6 @@ struct rte_console {
|
||||
/* manfid tuple length, include tuple, link bytes */
|
||||
#define SBSDIO_CIS_MANFID_TUPLE_LEN 6
|
||||
|
||||
-#define CORE_BUS_REG(base, field) \
|
||||
- (base + offsetof(struct sdpcmd_regs, field))
|
||||
#define SD_REG(field) \
|
||||
(offsetof(struct sdpcmd_regs, field))
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
From 21a10846d09db3c5e3bdfb0be0fc7aa9fdc7000a Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Fri, 8 Dec 2017 13:10:35 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove repeated calls to brcmf_chip_get_core()
|
||||
|
||||
There is no need to repeatdly call brcmf_chip_get_core(), which
|
||||
traverses a list of cores every time its called (including during
|
||||
register access code!).
|
||||
|
||||
Call it once, and store a pointer to the core structure. The existing
|
||||
code does nto keep track of users of the cores anyway, and even so, this
|
||||
will allow for easier refcounting in future.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 25 +++++++++++++---------
|
||||
1 file changed, 15 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -436,6 +436,7 @@ struct brcmf_sdio_count {
|
||||
struct brcmf_sdio {
|
||||
struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
|
||||
struct brcmf_chip *ci; /* Chip info struct */
|
||||
+ struct brcmf_core *sdio_core; /* sdio core info struct */
|
||||
|
||||
u32 hostintmask; /* Copy of Host Interrupt Mask */
|
||||
atomic_t intstatus; /* Intstatus bits (events) pending */
|
||||
@@ -665,10 +666,9 @@ static bool data_ok(struct brcmf_sdio *b
|
||||
*/
|
||||
static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
|
||||
{
|
||||
- struct brcmf_core *core;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
int ret;
|
||||
|
||||
- core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret);
|
||||
|
||||
return ret;
|
||||
@@ -676,10 +676,9 @@ static int r_sdreg32(struct brcmf_sdio *
|
||||
|
||||
static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
|
||||
{
|
||||
- struct brcmf_core *core;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
int ret;
|
||||
|
||||
- core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret);
|
||||
|
||||
return ret;
|
||||
@@ -2495,12 +2494,11 @@ static inline void brcmf_sdio_clrintr(st
|
||||
|
||||
static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
|
||||
{
|
||||
- struct brcmf_core *buscore;
|
||||
+ struct brcmf_core *buscore = bus->sdio_core;
|
||||
u32 addr;
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
- buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
addr = buscore->base + SD_REG(intstatus);
|
||||
|
||||
val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
|
||||
@@ -3377,13 +3375,14 @@ static void brcmf_sdio_sr_init(struct br
|
||||
/* enable KSO bit */
|
||||
static int brcmf_sdio_kso_init(struct brcmf_sdio *bus)
|
||||
{
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
u8 val;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* KSO bit added in SDIO core rev 12 */
|
||||
- if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
|
||||
+ if (core->rev < 12)
|
||||
return 0;
|
||||
|
||||
val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
|
||||
@@ -3412,6 +3411,7 @@ static int brcmf_sdio_bus_preinit(struct
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct brcmf_sdio *bus = sdiodev->bus;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
uint pad_size;
|
||||
u32 value;
|
||||
int err;
|
||||
@@ -3420,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct
|
||||
* a device perspective, ie. bus:txglom affects the
|
||||
* bus transfers from device to host.
|
||||
*/
|
||||
- if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
|
||||
+ if (core->rev < 12) {
|
||||
/* for sdio core rev < 12, disable txgloming */
|
||||
value = 0;
|
||||
err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
|
||||
@@ -3758,11 +3758,10 @@ static void brcmf_sdio_buscore_activate(
|
||||
u32 rstvec)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev = ctx;
|
||||
- struct brcmf_core *core;
|
||||
+ struct brcmf_core *core = sdiodev->bus->sdio_core;
|
||||
u32 reg_addr;
|
||||
|
||||
/* clear all interrupts */
|
||||
- core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
|
||||
reg_addr = core->base + SD_REG(intstatus);
|
||||
brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
|
||||
|
||||
@@ -3843,6 +3842,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
bus->ci = NULL;
|
||||
goto fail;
|
||||
}
|
||||
+
|
||||
+ /* Pick up the SDIO core info struct from chip.c */
|
||||
+ bus->sdio_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
+ if (!bus->sdio_core)
|
||||
+ goto fail;
|
||||
+
|
||||
sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
|
||||
BRCMF_BUSTYPE_SDIO,
|
||||
bus->ci->chip,
|
|
@ -0,0 +1,44 @@
|
|||
From 7762bb134e3b40e8ee2611365775b7432190a9c7 Mon Sep 17 00:00:00 2001
|
||||
From: Wright Feng <wright.feng@cypress.com>
|
||||
Date: Mon, 11 Dec 2017 15:38:21 +0800
|
||||
Subject: [PATCH] brcmfmac: enlarge buffer size of caps to 512 bytes
|
||||
|
||||
The buffer size of return of cap iovar is greater than 256 bytes in some
|
||||
firmwares. For instance, the return size of cap iovar is 271 bytes in 4373
|
||||
13.10.246.79 firmare. It makes feature capability parsing failed because
|
||||
caps buffer is default value.
|
||||
So we enlarge caps buffer size to 512 bytes and add the error print for
|
||||
cap iovar error.
|
||||
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -130,13 +130,19 @@ static void brcmf_feat_iovar_data_set(st
|
||||
}
|
||||
}
|
||||
|
||||
+#define MAX_CAPS_BUFFER_SIZE 512
|
||||
static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
|
||||
{
|
||||
- char caps[256];
|
||||
+ char caps[MAX_CAPS_BUFFER_SIZE];
|
||||
enum brcmf_feat_id id;
|
||||
- int i;
|
||||
+ int i, err;
|
||||
+
|
||||
+ err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
|
||||
+ if (err) {
|
||||
+ brcmf_err("could not get firmware cap (%d)\n", err);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
|
||||
brcmf_dbg(INFO, "[ %s]\n", caps);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
|
|
@ -0,0 +1,227 @@
|
|||
From 3d110df8f74781354051e4bb1e3e97fa368b2f80 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:07 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove {r,w}_sdreg32
|
||||
|
||||
Remove yet another IO function from the code and replace with one
|
||||
that already exists.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: keep address calculation, ie. (base + offset) in one line]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 88 +++++++++++-----------
|
||||
1 file changed, 42 insertions(+), 46 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -660,30 +660,6 @@ static bool data_ok(struct brcmf_sdio *b
|
||||
((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Reads a register in the SDIO hardware block. This block occupies a series of
|
||||
- * adresses on the 32 bit backplane bus.
|
||||
- */
|
||||
-static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
|
||||
-{
|
||||
- struct brcmf_core *core = bus->sdio_core;
|
||||
- int ret;
|
||||
-
|
||||
- *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
|
||||
-{
|
||||
- struct brcmf_core *core = bus->sdio_core;
|
||||
- int ret;
|
||||
-
|
||||
- brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
|
||||
{
|
||||
@@ -1078,6 +1054,8 @@ static void brcmf_sdio_get_console_addr(
|
||||
|
||||
static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
|
||||
{
|
||||
+ struct brcmf_sdio_dev *sdiod = bus->sdiodev;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
u32 intstatus = 0;
|
||||
u32 hmb_data;
|
||||
u8 fcbits;
|
||||
@@ -1086,10 +1064,14 @@ static u32 brcmf_sdio_hostmail(struct br
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
/* Read mailbox data and ack that we did so */
|
||||
- ret = r_sdreg32(bus, &hmb_data, SD_REG(tohostmailboxdata));
|
||||
+ hmb_data = brcmf_sdiod_readl(sdiod,
|
||||
+ core->base + SD_REG(tohostmailboxdata),
|
||||
+ &ret);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox),
|
||||
+ SMB_INT_ACK, &ret);
|
||||
|
||||
- if (ret == 0)
|
||||
- w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox));
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
|
||||
/* dongle indicates the firmware has halted/crashed */
|
||||
@@ -1163,6 +1145,8 @@ static u32 brcmf_sdio_hostmail(struct br
|
||||
|
||||
static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
|
||||
{
|
||||
+ struct brcmf_sdio_dev *sdiod = bus->sdiodev;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
uint retries = 0;
|
||||
u16 lastrbc;
|
||||
u8 hi, lo;
|
||||
@@ -1204,7 +1188,8 @@ static void brcmf_sdio_rxfail(struct brc
|
||||
|
||||
if (rtx) {
|
||||
bus->sdcnt.rxrtx++;
|
||||
- err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox));
|
||||
+ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox),
|
||||
+ SMB_NAK, &err);
|
||||
|
||||
bus->sdcnt.f1regdata++;
|
||||
if (err == 0)
|
||||
@@ -2291,6 +2276,7 @@ static uint brcmf_sdio_sendfromq(struct
|
||||
{
|
||||
struct sk_buff *pkt;
|
||||
struct sk_buff_head pktq;
|
||||
+ u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus);
|
||||
u32 intstatus = 0;
|
||||
int ret = 0, prec_out, i;
|
||||
uint cnt = 0;
|
||||
@@ -2329,7 +2315,8 @@ static uint brcmf_sdio_sendfromq(struct
|
||||
if (!bus->intr) {
|
||||
/* Check device status, signal pending interrupt */
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
- ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus));
|
||||
+ intstatus = brcmf_sdiod_readl(bus->sdiodev,
|
||||
+ intstat_addr, &ret);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
bus->sdcnt.f2txdata++;
|
||||
if (ret != 0)
|
||||
@@ -2413,12 +2400,13 @@ static int brcmf_sdio_tx_ctrlframe(struc
|
||||
|
||||
static void brcmf_sdio_bus_stop(struct device *dev)
|
||||
{
|
||||
- u32 local_hostintmask;
|
||||
- u8 saveclk;
|
||||
- int err;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct brcmf_sdio *bus = sdiodev->bus;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
+ u32 local_hostintmask;
|
||||
+ u8 saveclk;
|
||||
+ int err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
@@ -2435,7 +2423,9 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
brcmf_sdio_bus_sleep(bus, false, false);
|
||||
|
||||
/* Disable and clear interrupts at the chip level also */
|
||||
- w_sdreg32(bus, 0, SD_REG(hostintmask));
|
||||
+ brcmf_sdiod_writel(sdiodev, core->base + SD_REG(hostintmask),
|
||||
+ 0, NULL);
|
||||
+
|
||||
local_hostintmask = bus->hostintmask;
|
||||
bus->hostintmask = 0;
|
||||
|
||||
@@ -2454,7 +2444,8 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
/* Clear any pending interrupts now that F2 is disabled */
|
||||
- w_sdreg32(bus, local_hostintmask, SD_REG(intstatus));
|
||||
+ brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus),
|
||||
+ local_hostintmask, NULL);
|
||||
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
}
|
||||
@@ -2521,7 +2512,9 @@ static int brcmf_sdio_intr_rstatus(struc
|
||||
|
||||
static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
|
||||
{
|
||||
+ struct brcmf_sdio_dev *sdiod = bus->sdiodev;
|
||||
u32 newstatus = 0;
|
||||
+ u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus);
|
||||
unsigned long intstatus;
|
||||
uint txlimit = bus->txbound; /* Tx frames to send before resched */
|
||||
uint framecnt; /* Temporary counter of tx/rx frames */
|
||||
@@ -2576,9 +2569,10 @@ static void brcmf_sdio_dpc(struct brcmf_
|
||||
*/
|
||||
if (intstatus & I_HMB_FC_CHANGE) {
|
||||
intstatus &= ~I_HMB_FC_CHANGE;
|
||||
- err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus));
|
||||
+ brcmf_sdiod_writel(sdiod, intstat_addr, I_HMB_FC_CHANGE, &err);
|
||||
+
|
||||
+ newstatus = brcmf_sdiod_readl(sdiod, intstat_addr, &err);
|
||||
|
||||
- err = r_sdreg32(bus, &newstatus, SD_REG(intstatus));
|
||||
bus->sdcnt.f1regdata += 2;
|
||||
atomic_set(&bus->fcstate,
|
||||
!!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
|
||||
@@ -4017,22 +4011,21 @@ static void brcmf_sdio_firmware_callback
|
||||
const struct firmware *code,
|
||||
void *nvram, u32 nvram_len)
|
||||
{
|
||||
- struct brcmf_bus *bus_if;
|
||||
- struct brcmf_sdio_dev *sdiodev;
|
||||
- struct brcmf_sdio *bus;
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
+ struct brcmf_sdio *bus = sdiodev->bus;
|
||||
+ struct brcmf_sdio_dev *sdiod = bus->sdiodev;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
u8 saveclk;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
|
||||
- bus_if = dev_get_drvdata(dev);
|
||||
- sdiodev = bus_if->bus_priv.sdio;
|
||||
+
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
if (!bus_if->drvr)
|
||||
return;
|
||||
|
||||
- bus = sdiodev->bus;
|
||||
-
|
||||
/* try to download image and nvram to the dongle */
|
||||
bus->alp_only = true;
|
||||
err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
|
||||
@@ -4063,8 +4056,9 @@ static void brcmf_sdio_firmware_callback
|
||||
}
|
||||
|
||||
/* Enable function 2 (frame transfers) */
|
||||
- w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
|
||||
- SD_REG(tosbmailboxdata));
|
||||
+ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata),
|
||||
+ SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL);
|
||||
+
|
||||
err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
|
||||
|
||||
@@ -4074,7 +4068,9 @@ static void brcmf_sdio_firmware_callback
|
||||
if (!err) {
|
||||
/* Set up the interrupt mask and enable interrupts */
|
||||
bus->hostintmask = HOSTINTMASK;
|
||||
- w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask));
|
||||
+ brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask),
|
||||
+ bus->hostintmask, NULL);
|
||||
+
|
||||
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
} else {
|
|
@ -0,0 +1,33 @@
|
|||
From dbda7dacb79a377e8ed9d38ce0e4a58b70aa9060 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Tue, 19 Dec 2017 13:47:08 +0100
|
||||
Subject: [PATCH] brcmfmac: Rename buscore to core for consistency
|
||||
|
||||
Avoid confusion with unrelated _buscore labels.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: only do the rename]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -2485,12 +2485,12 @@ static inline void brcmf_sdio_clrintr(st
|
||||
|
||||
static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
|
||||
{
|
||||
- struct brcmf_core *buscore = bus->sdio_core;
|
||||
+ struct brcmf_core *core = bus->sdio_core;
|
||||
u32 addr;
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
- addr = buscore->base + SD_REG(intstatus);
|
||||
+ addr = core->base + SD_REG(intstatus);
|
||||
|
||||
val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
|
||||
bus->sdcnt.f1regdata++;
|
|
@ -0,0 +1,82 @@
|
|||
From 874bb8e49b7c6368f8ff9f2566c7bd06a2249be0 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:09 +0100
|
||||
Subject: [PATCH] brcmfmac: stabilise the value of ->sbwad in use for some xfer
|
||||
routines.
|
||||
|
||||
The IO functions operate within the Chipcommon IO window. Explicitly
|
||||
set this, rather than relying on the last initialisation IO access to
|
||||
leave it set to the right value by chance.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++----
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 1 +
|
||||
3 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -529,7 +529,7 @@ int brcmf_sdiod_recv_buf(struct brcmf_sd
|
||||
|
||||
int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
|
||||
{
|
||||
- u32 addr = sdiodev->sbwad;
|
||||
+ u32 addr = sdiodev->cc_core->base;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
|
||||
@@ -552,7 +552,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
{
|
||||
struct sk_buff *glom_skb = NULL;
|
||||
struct sk_buff *skb;
|
||||
- u32 addr = sdiodev->sbwad;
|
||||
+ u32 addr = sdiodev->cc_core->base;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
|
||||
@@ -593,7 +593,7 @@ done:
|
||||
int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
|
||||
{
|
||||
struct sk_buff *mypkt;
|
||||
- u32 addr = sdiodev->sbwad;
|
||||
+ u32 addr = sdiodev->cc_core->base;
|
||||
int err;
|
||||
|
||||
mypkt = brcmu_pkt_buf_get_skb(nbytes);
|
||||
@@ -625,7 +625,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
struct sk_buff_head *pktq)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
- u32 addr = sdiodev->sbwad;
|
||||
+ u32 addr = sdiodev->cc_core->base;
|
||||
int err;
|
||||
|
||||
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3842,6 +3842,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
if (!bus->sdio_core)
|
||||
goto fail;
|
||||
|
||||
+ /* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */
|
||||
+ sdiodev->cc_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_CHIPCOMMON);
|
||||
+ if (!sdiodev->cc_core)
|
||||
+ goto fail;
|
||||
+
|
||||
sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
|
||||
BRCMF_BUSTYPE_SDIO,
|
||||
bus->ci->chip,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -178,6 +178,7 @@ struct brcmf_sdio_dev {
|
||||
struct sdio_func *func[SDIO_MAX_FUNCS];
|
||||
u8 num_funcs; /* Supported funcs on client */
|
||||
u32 sbwad; /* Save backplane window address */
|
||||
+ struct brcmf_core *cc_core; /* chipcommon core info struct */
|
||||
struct brcmf_sdio *bus;
|
||||
struct device *dev;
|
||||
struct brcmf_bus *bus_if;
|
|
@ -0,0 +1,45 @@
|
|||
From 508422f3695bf66f7b85fb4723c22f5166003ec6 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:10 +0100
|
||||
Subject: [PATCH] brcmfmac: Correctly handle accesses to SDIO func0
|
||||
|
||||
Rather than workaround the restrictions on func0 addressing in the
|
||||
driver, set MMC_QUIRK_LENIENT_FN0
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 4 ++--
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -995,6 +995,10 @@ static int brcmf_ops_sdio_probe(struct s
|
||||
brcmf_dbg(SDIO, "Function#: %d\n", func->num);
|
||||
|
||||
dev = &func->dev;
|
||||
+
|
||||
+ /* Set MMC_QUIRK_LENIENT_FN0 for this card */
|
||||
+ func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
|
||||
+
|
||||
/* prohibit ACPI power management for this device */
|
||||
brcmf_sdiod_acpi_set_power_manageable(dev, 0);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct
|
||||
/* SDIO device register access interface */
|
||||
/* Accessors for SDIO Function 0 */
|
||||
#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
|
||||
- sdio_readb((sdiodev)->func[0], (addr), (r))
|
||||
+ sdio_f0_readb((sdiodev)->func[0], (addr), (r))
|
||||
|
||||
#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
|
||||
- sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
|
||||
+ sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
|
||||
|
||||
/* Accessors for SDIO Function 1 */
|
||||
#define brcmf_sdiod_readb(sdiodev, addr, r) \
|
|
@ -0,0 +1,111 @@
|
|||
From 99d7b6fdfc8c24052c92c720330d31ca1332f996 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:11 +0100
|
||||
Subject: [PATCH] brcmfmac: Remove func0 from function array
|
||||
|
||||
func0 is not provided by the mmc stack as a function when probing.
|
||||
Instead providing specific access functions to read/write it.
|
||||
|
||||
This prepares for a patch to remove the actual array entry itself.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: rephrased the commit message]
|
||||
[arend: removed unrelated comment for which separate patch is warranted]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +----
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 ++++---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 13 ++++++-------
|
||||
3 files changed, 11 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -1022,8 +1022,7 @@ static int brcmf_ops_sdio_probe(struct s
|
||||
/* store refs to functions used. mmc_card does
|
||||
* not hold the F0 function pointer.
|
||||
*/
|
||||
- sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
|
||||
- sdiodev->func[0]->num = 0;
|
||||
+ sdiodev->func[0] = NULL;
|
||||
sdiodev->func[1] = func->card->sdio_func[0];
|
||||
sdiodev->func[2] = func;
|
||||
|
||||
@@ -1049,7 +1048,6 @@ static int brcmf_ops_sdio_probe(struct s
|
||||
fail:
|
||||
dev_set_drvdata(&func->dev, NULL);
|
||||
dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
|
||||
- kfree(sdiodev->func[0]);
|
||||
kfree(sdiodev);
|
||||
kfree(bus_if);
|
||||
return err;
|
||||
@@ -1082,7 +1080,6 @@ static void brcmf_ops_sdio_remove(struct
|
||||
dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
|
||||
|
||||
kfree(bus_if);
|
||||
- kfree(sdiodev->func[0]);
|
||||
kfree(sdiodev);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3771,9 +3771,10 @@ static u32 brcmf_sdio_buscore_read32(voi
|
||||
u32 val, rev;
|
||||
|
||||
val = brcmf_sdiod_readl(sdiodev, addr, NULL);
|
||||
- if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
|
||||
- sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
|
||||
- addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
+
|
||||
+ if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
|
||||
+ sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
|
||||
+ addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
|
||||
if (rev >= 2) {
|
||||
val &= ~CID_ID_MASK;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -21,7 +21,9 @@
|
||||
#include <linux/firmware.h>
|
||||
#include "firmware.h"
|
||||
|
||||
-#define SDIO_FUNC_0 0
|
||||
+/* Maximum number of I/O funcs */
|
||||
+#define NUM_SDIO_FUNCS 3
|
||||
+
|
||||
#define SDIO_FUNC_1 1
|
||||
#define SDIO_FUNC_2 2
|
||||
|
||||
@@ -39,9 +41,6 @@
|
||||
#define INTR_STATUS_FUNC1 0x2
|
||||
#define INTR_STATUS_FUNC2 0x4
|
||||
|
||||
-/* Maximum number of I/O funcs */
|
||||
-#define SDIOD_MAX_IOFUNCS 7
|
||||
-
|
||||
/* mask of register map */
|
||||
#define REG_F0_REG_MASK 0x7FF
|
||||
#define REG_F1_MISC_MASK 0x1FFFF
|
||||
@@ -175,7 +174,7 @@ struct brcmf_sdio;
|
||||
struct brcmf_sdiod_freezer;
|
||||
|
||||
struct brcmf_sdio_dev {
|
||||
- struct sdio_func *func[SDIO_MAX_FUNCS];
|
||||
+ struct sdio_func *func[NUM_SDIO_FUNCS];
|
||||
u8 num_funcs; /* Supported funcs on client */
|
||||
u32 sbwad; /* Save backplane window address */
|
||||
struct brcmf_core *cc_core; /* chipcommon core info struct */
|
||||
@@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct
|
||||
/* SDIO device register access interface */
|
||||
/* Accessors for SDIO Function 0 */
|
||||
#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
|
||||
- sdio_f0_readb((sdiodev)->func[0], (addr), (r))
|
||||
+ sdio_f0_readb((sdiodev)->func[1], (addr), (r))
|
||||
|
||||
#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
|
||||
- sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
|
||||
+ sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret))
|
||||
|
||||
/* Accessors for SDIO Function 1 */
|
||||
#define brcmf_sdiod_readb(sdiodev, addr, r) \
|
|
@ -0,0 +1,40 @@
|
|||
From bcadaaa097c7ec103fe75f9da41f8fe52693b644 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Tue, 19 Dec 2017 13:47:12 +0100
|
||||
Subject: [PATCH] brcmfmac: More efficient and slightly easier to read fixup
|
||||
for 4339 chips
|
||||
|
||||
Its more efficient to test the register we're interested in first,
|
||||
potentially avoiding two more comparisons, and therefore always avoiding
|
||||
one comparison per call on all other chips.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
[arend: fix some checkpatch warnings]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3772,15 +3772,16 @@ static u32 brcmf_sdio_buscore_read32(voi
|
||||
|
||||
val = brcmf_sdiod_readl(sdiodev, addr, NULL);
|
||||
|
||||
- if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
|
||||
- sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
|
||||
- addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
+ if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) &&
|
||||
+ (sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339 ||
|
||||
+ sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) {
|
||||
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
|
||||
if (rev >= 2) {
|
||||
val &= ~CID_ID_MASK;
|
||||
val |= BRCM_CC_4339_CHIP_ID;
|
||||
}
|
||||
}
|
||||
+
|
||||
return val;
|
||||
}
|
||||
|
|
@ -0,0 +1,347 @@
|
|||
From 00eb62cfc5f806b003fe5d54c8b5fe9a9665482f Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:13 +0100
|
||||
Subject: [PATCH] brcmfmac: Replace function index with function pointer
|
||||
|
||||
In preparation for removing the function array, remove all code that
|
||||
refers to function by index and replace with pointers to the function
|
||||
itself.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
[arend: replace BUG() with WARN() macro]
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 85 ++++++++++++----------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 15 ++--
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 6 +-
|
||||
3 files changed, 56 insertions(+), 50 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -291,8 +291,9 @@ out:
|
||||
*ret = retval;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
- u32 addr, struct sk_buff *pkt)
|
||||
+static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev,
|
||||
+ struct sdio_func *func, u32 addr,
|
||||
+ struct sk_buff *pkt)
|
||||
{
|
||||
unsigned int req_sz;
|
||||
int err;
|
||||
@@ -301,13 +302,19 @@ static int brcmf_sdiod_buff_read(struct
|
||||
req_sz = pkt->len + 3;
|
||||
req_sz &= (uint)~3;
|
||||
|
||||
- if (fn == 1)
|
||||
- err = sdio_memcpy_fromio(sdiodev->func[fn],
|
||||
- ((u8 *)(pkt->data)), addr, req_sz);
|
||||
- else
|
||||
- /* function 2 read is FIFO operation */
|
||||
- err = sdio_readsb(sdiodev->func[fn],
|
||||
- ((u8 *)(pkt->data)), addr, req_sz);
|
||||
+ switch (func->num) {
|
||||
+ case 1:
|
||||
+ err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr,
|
||||
+ req_sz);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz);
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* bail out as things are really fishy here */
|
||||
+ WARN(1, "invalid sdio function number: %d\n", func->num);
|
||||
+ err = -ENOMEDIUM;
|
||||
+ };
|
||||
|
||||
if (err == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
@@ -315,8 +322,9 @@ static int brcmf_sdiod_buff_read(struct
|
||||
return err;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
- u32 addr, struct sk_buff *pkt)
|
||||
+static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev,
|
||||
+ struct sdio_func *func, u32 addr,
|
||||
+ struct sk_buff *pkt)
|
||||
{
|
||||
unsigned int req_sz;
|
||||
int err;
|
||||
@@ -325,8 +333,7 @@ static int brcmf_sdiod_buff_write(struct
|
||||
req_sz = pkt->len + 3;
|
||||
req_sz &= (uint)~3;
|
||||
|
||||
- err = sdio_memcpy_toio(sdiodev->func[fn], addr,
|
||||
- ((u8 *)(pkt->data)), req_sz);
|
||||
+ err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz);
|
||||
|
||||
if (err == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
@@ -337,7 +344,7 @@ static int brcmf_sdiod_buff_write(struct
|
||||
/**
|
||||
* brcmf_sdiod_sglist_rw - SDIO interface function for block data access
|
||||
* @sdiodev: brcmfmac sdio device
|
||||
- * @fn: SDIO function number
|
||||
+ * @func: SDIO function
|
||||
* @write: direction flag
|
||||
* @addr: dongle memory address as source/destination
|
||||
* @pkt: skb pointer
|
||||
@@ -346,7 +353,8 @@ static int brcmf_sdiod_buff_write(struct
|
||||
* stack for block data access. It assumes that the skb passed down by the
|
||||
* caller has already been padded and aligned.
|
||||
*/
|
||||
-static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
|
||||
+static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev,
|
||||
+ struct sdio_func *func,
|
||||
bool write, u32 addr,
|
||||
struct sk_buff_head *pktlist)
|
||||
{
|
||||
@@ -372,7 +380,7 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
req_sz = 0;
|
||||
skb_queue_walk(pktlist, pkt_next)
|
||||
req_sz += pkt_next->len;
|
||||
- req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
|
||||
+ req_sz = ALIGN(req_sz, func->cur_blksize);
|
||||
while (req_sz > PAGE_SIZE) {
|
||||
pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
|
||||
if (pkt_next == NULL) {
|
||||
@@ -391,7 +399,7 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
target_list = &local_list;
|
||||
}
|
||||
|
||||
- func_blk_sz = sdiodev->func[fn]->cur_blksize;
|
||||
+ func_blk_sz = func->cur_blksize;
|
||||
max_req_sz = sdiodev->max_request_size;
|
||||
max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
|
||||
target_list->qlen);
|
||||
@@ -408,10 +416,10 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
|
||||
mmc_cmd.opcode = SD_IO_RW_EXTENDED;
|
||||
mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */
|
||||
- mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */
|
||||
- mmc_cmd.arg |= 1<<27; /* block mode */
|
||||
+ mmc_cmd.arg |= (func->num & 0x7) << 28; /* SDIO func num */
|
||||
+ mmc_cmd.arg |= 1 << 27; /* block mode */
|
||||
/* for function 1 the addr will be incremented */
|
||||
- mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
|
||||
+ mmc_cmd.arg |= (func->num == 1) ? 1 << 26 : 0;
|
||||
mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
|
||||
mmc_req.cmd = &mmc_cmd;
|
||||
mmc_req.data = &mmc_dat;
|
||||
@@ -457,11 +465,11 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */
|
||||
mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */
|
||||
/* incrementing addr for function 1 */
|
||||
- if (fn == 1)
|
||||
+ if (func->num == 1)
|
||||
addr += req_sz;
|
||||
|
||||
- mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
|
||||
- mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
|
||||
+ mmc_set_data_timeout(&mmc_dat, func->card);
|
||||
+ mmc_wait_for_req(func->card->host, &mmc_req);
|
||||
|
||||
ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
|
||||
if (ret == -ENOMEDIUM) {
|
||||
@@ -541,7 +549,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, pkt);
|
||||
|
||||
done:
|
||||
return err;
|
||||
@@ -566,13 +574,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
if (pktq->qlen == 1)
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr,
|
||||
pktq->next);
|
||||
else if (!sdiodev->sg_support) {
|
||||
glom_skb = brcmu_pkt_buf_get_skb(totlen);
|
||||
if (!glom_skb)
|
||||
return -ENOMEM;
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr,
|
||||
glom_skb);
|
||||
if (err)
|
||||
goto done;
|
||||
@@ -582,8 +590,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
skb_pull(glom_skb, skb->len);
|
||||
}
|
||||
} else
|
||||
- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,
|
||||
- pktq);
|
||||
+ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], false,
|
||||
+ addr, pktq);
|
||||
|
||||
done:
|
||||
brcmu_pkt_buf_free_skb(glom_skb);
|
||||
@@ -614,7 +622,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
if (!err)
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], addr,
|
||||
+ mypkt);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
|
||||
@@ -639,14 +648,14 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
|
||||
if (pktq->qlen == 1 || !sdiodev->sg_support) {
|
||||
skb_queue_walk(pktq, skb) {
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2],
|
||||
addr, skb);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
|
||||
- pktq);
|
||||
+ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], true,
|
||||
+ addr, pktq);
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -696,10 +705,10 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
|
||||
if (write) {
|
||||
memcpy(pkt->data, data, dsize);
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1,
|
||||
+ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[1],
|
||||
sdaddr, pkt);
|
||||
} else {
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1,
|
||||
+ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[1],
|
||||
sdaddr, pkt);
|
||||
}
|
||||
|
||||
@@ -728,12 +737,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
return err;
|
||||
}
|
||||
|
||||
-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
|
||||
+int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func)
|
||||
{
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
/* Issue abort cmd52 command through F0 */
|
||||
- brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL);
|
||||
+ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, func->num, NULL);
|
||||
|
||||
brcmf_dbg(SDIO, "Exit\n");
|
||||
return 0;
|
||||
@@ -1105,7 +1114,7 @@ static int brcmf_ops_sdio_suspend(struct
|
||||
|
||||
func = container_of(dev, struct sdio_func, dev);
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
- if (func->num != SDIO_FUNC_1)
|
||||
+ if (func->num != 1)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1134,7 +1143,7 @@ static int brcmf_ops_sdio_resume(struct
|
||||
struct sdio_func *func = container_of(dev, struct sdio_func, dev);
|
||||
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
- if (func->num != SDIO_FUNC_2)
|
||||
+ if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
brcmf_sdiod_freezer_off(sdiodev);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -1157,7 +1157,7 @@ static void brcmf_sdio_rxfail(struct brc
|
||||
rtx ? ", send NAK" : "");
|
||||
|
||||
if (abort)
|
||||
- brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
|
||||
+ brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func[2]);
|
||||
|
||||
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
|
||||
&err);
|
||||
@@ -1209,7 +1209,7 @@ static void brcmf_sdio_txfail(struct brc
|
||||
brcmf_err("sdio error, abort command and terminate frame\n");
|
||||
bus->sdcnt.tx_sderrs++;
|
||||
|
||||
- brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
|
||||
+ brcmf_sdiod_abort(sdiodev, sdiodev->func[2]);
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
|
||||
bus->sdcnt.f1regdata++;
|
||||
|
||||
@@ -2072,7 +2072,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru
|
||||
int ntail, ret;
|
||||
|
||||
sdiodev = bus->sdiodev;
|
||||
- blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
|
||||
+ blksize = sdiodev->func[2]->cur_blksize;
|
||||
/* sg entry alignment should be a divisor of block size */
|
||||
WARN_ON(blksize % bus->sgentry_align);
|
||||
|
||||
@@ -2441,7 +2441,7 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
|
||||
/* Turn off the bus (F2), free any pending packets */
|
||||
brcmf_dbg(INTR, "disable SDIO interrupts\n");
|
||||
- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
+ sdio_disable_func(sdiodev->func[2]);
|
||||
|
||||
/* Clear any pending interrupts now that F2 is disabled */
|
||||
brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus),
|
||||
@@ -4066,8 +4066,7 @@ static void brcmf_sdio_firmware_callback
|
||||
brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata),
|
||||
SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL);
|
||||
|
||||
- err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
-
|
||||
+ err = sdio_enable_func(sdiodev->func[2]);
|
||||
|
||||
brcmf_dbg(INFO, "enable F2: err=%d\n", err);
|
||||
|
||||
@@ -4082,7 +4081,7 @@ static void brcmf_sdio_firmware_callback
|
||||
brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
|
||||
} else {
|
||||
/* Disable F2 again */
|
||||
- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
|
||||
+ sdio_disable_func(sdiodev->func[2]);
|
||||
goto release;
|
||||
}
|
||||
|
||||
@@ -4219,7 +4218,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
|
||||
/* Disable F2 to clear any intermediate frame state on the dongle */
|
||||
- sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
|
||||
+ sdio_disable_func(bus->sdiodev->func[2]);
|
||||
|
||||
bus->rxflow = false;
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -45,9 +45,6 @@
|
||||
#define REG_F0_REG_MASK 0x7FF
|
||||
#define REG_F1_MISC_MASK 0x1FFFF
|
||||
|
||||
-/* as of sdiod rev 0, supports 3 functions */
|
||||
-#define SBSDIO_NUM_FUNCTION 3
|
||||
-
|
||||
/* function 0 vendor specific CCCR registers */
|
||||
|
||||
#define SDIO_CCCR_BRCM_CARDCAP 0xf0
|
||||
@@ -350,7 +347,8 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_
|
||||
u8 *data, uint size);
|
||||
|
||||
/* Issue an abort to the specified function */
|
||||
-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn);
|
||||
+int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func);
|
||||
+
|
||||
void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev);
|
||||
void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
|
||||
enum brcmf_sdiod_state state);
|
|
@ -0,0 +1,53 @@
|
|||
From 9c3438ed215adba7025268ee1f0b6f7a2af12316 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Molton <ian@mnementh.co.uk>
|
||||
Date: Tue, 19 Dec 2017 13:47:14 +0100
|
||||
Subject: [PATCH] brcmfmac: Clean up interrupt macros
|
||||
|
||||
Make it more obvious that this code acually enables interrupts, and
|
||||
provide nice definitions for the bits in the register.
|
||||
|
||||
Signed-off-by: Ian Molton <ian@mnementh.co.uk>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 8 +++++---
|
||||
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -149,7 +149,8 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
|
||||
/* must configure SDIO_CCCR_IENx to enable irq */
|
||||
data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);
|
||||
- data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
|
||||
+ data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 |
|
||||
+ SDIO_CCCR_IEN_FUNC0;
|
||||
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
|
||||
|
||||
/* redirect, configure and enable io for interrupt signal */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -24,9 +24,6 @@
|
||||
/* Maximum number of I/O funcs */
|
||||
#define NUM_SDIO_FUNCS 3
|
||||
|
||||
-#define SDIO_FUNC_1 1
|
||||
-#define SDIO_FUNC_2 2
|
||||
-
|
||||
#define SDIOD_FBR_SIZE 0x100
|
||||
|
||||
/* io_en */
|
||||
@@ -52,6 +49,11 @@
|
||||
#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2)
|
||||
#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3)
|
||||
|
||||
+/* Interrupt enable bits for each function */
|
||||
+#define SDIO_CCCR_IEN_FUNC0 BIT(0)
|
||||
+#define SDIO_CCCR_IEN_FUNC1 BIT(1)
|
||||
+#define SDIO_CCCR_IEN_FUNC2 BIT(2)
|
||||
+
|
||||
#define SDIO_CCCR_BRCM_CARDCTRL 0xf1
|
||||
#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET BIT(1)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From e3720dad99859251a8b0fe2807275a8afcfb560d Mon Sep 17 00:00:00 2001
|
||||
From: Double Lo <double.lo@cypress.com>
|
||||
Date: Tue, 19 Dec 2017 14:56:44 +0800
|
||||
Subject: [PATCH] brcmfmac: Support 43455 save-restore (SR) feature if FW
|
||||
include -sr
|
||||
|
||||
This patch will add 43455 into the save-restore(SR) capable chip list, so
|
||||
the SR engine will be enabled with 43455 FW which built-in the -sr
|
||||
function.
|
||||
|
||||
Signed-off-by: Double Lo <double.lo@cypress.com>
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -1338,6 +1338,7 @@ bool brcmf_chip_sr_capable(struct brcmf_
|
||||
switch (pub->chip) {
|
||||
case BRCM_CC_4354_CHIP_ID:
|
||||
case BRCM_CC_4356_CHIP_ID:
|
||||
+ case BRCM_CC_4345_CHIP_ID:
|
||||
/* explicitly check SR engine enable bit */
|
||||
pmu_cc3_mask = BIT(2);
|
||||
/* fall-through */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,31 @@
|
|||
From 32adbcaa5df49f1977441f7a4bf180a0bcfe9966 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Tue, 9 Jan 2018 13:22:53 +0100
|
||||
Subject: [PATCH] brcmfmac: add comment block in brcmf_sdio_buscore_read()
|
||||
|
||||
In brcmf_sdio_buscore_read() there is some special handling upon
|
||||
register access to chipid register of the chipcommon core. Add
|
||||
comment explaining why it is done here.
|
||||
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3772,6 +3772,13 @@ static u32 brcmf_sdio_buscore_read32(voi
|
||||
|
||||
val = brcmf_sdiod_readl(sdiodev, addr, NULL);
|
||||
|
||||
+ /*
|
||||
+ * this is a bit of special handling if reading the chipcommon chipid
|
||||
+ * register. The 4339 is a next-gen of the 4335. It uses the same
|
||||
+ * SDIO device id as 4335 and the chipid register returns 4335 as well.
|
||||
+ * It can be identified as 4339 by looking at the chip revision. It
|
||||
+ * is corrected here so the chip.c module has the right info.
|
||||
+ */
|
||||
if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) &&
|
||||
(sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4339 ||
|
||||
sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) {
|
|
@ -0,0 +1,137 @@
|
|||
From 378f6a16043e5d3346301fc618f503e97aea335b Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Tue, 9 Jan 2018 13:22:54 +0100
|
||||
Subject: [PATCH] brcmfmac: rename brcmf_sdiod_buff_{read,write}() functions
|
||||
|
||||
Rename functions to brcmf_sdio_skbuff_{read,write}() as we pass an
|
||||
skbuff to this function.
|
||||
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 48 +++++++++++-----------
|
||||
1 file changed, 24 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -292,24 +292,24 @@ out:
|
||||
*ret = retval;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev,
|
||||
- struct sdio_func *func, u32 addr,
|
||||
- struct sk_buff *pkt)
|
||||
+static int brcmf_sdiod_skbuff_read(struct brcmf_sdio_dev *sdiodev,
|
||||
+ struct sdio_func *func, u32 addr,
|
||||
+ struct sk_buff *skb)
|
||||
{
|
||||
unsigned int req_sz;
|
||||
int err;
|
||||
|
||||
/* Single skb use the standard mmc interface */
|
||||
- req_sz = pkt->len + 3;
|
||||
+ req_sz = skb->len + 3;
|
||||
req_sz &= (uint)~3;
|
||||
|
||||
switch (func->num) {
|
||||
case 1:
|
||||
- err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr,
|
||||
+ err = sdio_memcpy_fromio(func, ((u8 *)(skb->data)), addr,
|
||||
req_sz);
|
||||
break;
|
||||
case 2:
|
||||
- err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz);
|
||||
+ err = sdio_readsb(func, ((u8 *)(skb->data)), addr, req_sz);
|
||||
break;
|
||||
default:
|
||||
/* bail out as things are really fishy here */
|
||||
@@ -323,18 +323,18 @@ static int brcmf_sdiod_buff_read(struct
|
||||
return err;
|
||||
}
|
||||
|
||||
-static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev,
|
||||
- struct sdio_func *func, u32 addr,
|
||||
- struct sk_buff *pkt)
|
||||
+static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev,
|
||||
+ struct sdio_func *func, u32 addr,
|
||||
+ struct sk_buff *skb)
|
||||
{
|
||||
unsigned int req_sz;
|
||||
int err;
|
||||
|
||||
/* Single skb use the standard mmc interface */
|
||||
- req_sz = pkt->len + 3;
|
||||
+ req_sz = skb->len + 3;
|
||||
req_sz &= (uint)~3;
|
||||
|
||||
- err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz);
|
||||
+ err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz);
|
||||
|
||||
if (err == -ENOMEDIUM)
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
|
||||
@@ -550,7 +550,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, pkt);
|
||||
+ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, pkt);
|
||||
|
||||
done:
|
||||
return err;
|
||||
@@ -575,14 +575,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
if (pktq->qlen == 1)
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr,
|
||||
- pktq->next);
|
||||
+ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr,
|
||||
+ pktq->next);
|
||||
else if (!sdiodev->sg_support) {
|
||||
glom_skb = brcmu_pkt_buf_get_skb(totlen);
|
||||
if (!glom_skb)
|
||||
return -ENOMEM;
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr,
|
||||
- glom_skb);
|
||||
+ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr,
|
||||
+ glom_skb);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
@@ -623,8 +623,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
if (!err)
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, addr,
|
||||
- mypkt);
|
||||
+ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr,
|
||||
+ mypkt);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
|
||||
@@ -649,8 +649,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
|
||||
|
||||
if (pktq->qlen == 1 || !sdiodev->sg_support) {
|
||||
skb_queue_walk(pktq, skb) {
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2,
|
||||
- addr, skb);
|
||||
+ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2,
|
||||
+ addr, skb);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -706,11 +706,11 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
|
||||
|
||||
if (write) {
|
||||
memcpy(pkt->data, data, dsize);
|
||||
- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func1,
|
||||
- sdaddr, pkt);
|
||||
+ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func1,
|
||||
+ sdaddr, pkt);
|
||||
} else {
|
||||
- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func1,
|
||||
- sdaddr, pkt);
|
||||
+ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func1,
|
||||
+ sdaddr, pkt);
|
||||
}
|
||||
|
||||
if (err) {
|
|
@ -0,0 +1,59 @@
|
|||
From b7acadaf038740c43515dc1548f43d01cc92823a Mon Sep 17 00:00:00 2001
|
||||
From: Himanshu Jha <himanshujha199640@gmail.com>
|
||||
Date: Tue, 9 Jan 2018 02:15:31 +0530
|
||||
Subject: [PATCH] brcmfmac: Use zeroing memory allocator than allocator/memset
|
||||
|
||||
Use dma_zalloc_coherent for allocating zeroed
|
||||
memory and remove unnecessary memset function.
|
||||
|
||||
Generated-by: scripts/coccinelle/api/alloc/kzalloc-simple.cocci
|
||||
|
||||
Suggested-by: Luis R. Rodriguez <mcgrof@kernel.org>
|
||||
Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -1251,14 +1251,14 @@ static int brcmf_pcie_init_scratchbuffer
|
||||
u64 address;
|
||||
u32 addr;
|
||||
|
||||
- devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev,
|
||||
- BRCMF_DMA_D2H_SCRATCH_BUF_LEN,
|
||||
- &devinfo->shared.scratch_dmahandle, GFP_KERNEL);
|
||||
+ devinfo->shared.scratch =
|
||||
+ dma_zalloc_coherent(&devinfo->pdev->dev,
|
||||
+ BRCMF_DMA_D2H_SCRATCH_BUF_LEN,
|
||||
+ &devinfo->shared.scratch_dmahandle,
|
||||
+ GFP_KERNEL);
|
||||
if (!devinfo->shared.scratch)
|
||||
goto fail;
|
||||
|
||||
- memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
|
||||
-
|
||||
addr = devinfo->shared.tcm_base_address +
|
||||
BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET;
|
||||
address = (u64)devinfo->shared.scratch_dmahandle;
|
||||
@@ -1268,14 +1268,14 @@ static int brcmf_pcie_init_scratchbuffer
|
||||
BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET;
|
||||
brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
|
||||
|
||||
- devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev,
|
||||
- BRCMF_DMA_D2H_RINGUPD_BUF_LEN,
|
||||
- &devinfo->shared.ringupd_dmahandle, GFP_KERNEL);
|
||||
+ devinfo->shared.ringupd =
|
||||
+ dma_zalloc_coherent(&devinfo->pdev->dev,
|
||||
+ BRCMF_DMA_D2H_RINGUPD_BUF_LEN,
|
||||
+ &devinfo->shared.ringupd_dmahandle,
|
||||
+ GFP_KERNEL);
|
||||
if (!devinfo->shared.ringupd)
|
||||
goto fail;
|
||||
|
||||
- memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
|
||||
-
|
||||
addr = devinfo->shared.tcm_base_address +
|
||||
BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET;
|
||||
address = (u64)devinfo->shared.ringupd_dmahandle;
|
|
@ -0,0 +1,26 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 9 Feb 2018 19:46:54 +0100
|
||||
Subject: [PATCH] mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple
|
||||
of 4
|
||||
|
||||
This ensures that mac80211 allocated management frames are properly
|
||||
aligned, which makes copying them more efficient.
|
||||
For instance, mt76 uses iowrite32_copy to copy beacon frames to beacon
|
||||
template memory on the chip.
|
||||
Misaligned 32-bit accesses cause CPU exceptions on MIPS and should be
|
||||
avoided.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4145,7 +4145,7 @@ void ieee80211_sta_uapsd_trigger(struct
|
||||
* The TX headroom reserved by mac80211 for its own tx_status functions.
|
||||
* This is enough for the radiotap header.
|
||||
*/
|
||||
-#define IEEE80211_TX_STATUS_HEADROOM 14
|
||||
+#define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4)
|
||||
|
||||
/**
|
||||
* ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
|
|
@ -0,0 +1,21 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 23 Feb 2018 09:59:35 +0100
|
||||
Subject: [PATCH] mac80211: drop frames with unexpected DS bits from
|
||||
fast-rx to slow path
|
||||
|
||||
Fixes rx for 4-addr packets in AP mode
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3928,7 +3928,7 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS |
|
||||
IEEE80211_FCTL_TODS)) !=
|
||||
fast_rx->expected_ds_bits)
|
||||
- goto drop;
|
||||
+ return false;
|
||||
|
||||
/* assign the key to drop unencrypted frames (later)
|
||||
* and strip the IV/MIC if necessary
|
|
@ -0,0 +1,25 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 23 Feb 2018 10:00:22 +0100
|
||||
Subject: [PATCH] mac80211: support AP 4-addr mode fast-rx
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3774,6 +3774,15 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
|
||||
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
|
||||
!sdata->u.vlan.sta);
|
||||
+
|
||||
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
|
||||
+ sdata->u.vlan.sta) {
|
||||
+ fastrx.expected_ds_bits |=
|
||||
+ cpu_to_le16(IEEE80211_FCTL_FROMDS);
|
||||
+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
||||
+ fastrx.internal_forward = 0;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
default:
|
||||
goto clear;
|
|
@ -0,0 +1,53 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 23 Feb 2018 10:01:53 +0100
|
||||
Subject: [PATCH] mac80211: support fast-rx with incompatible PS
|
||||
capabilities when PS is disabled
|
||||
|
||||
When powersave is disabled for the interface, we can do fast-rx anyway.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2658,6 +2658,7 @@ static int ieee80211_set_power_mgmt(stru
|
||||
|
||||
ieee80211_recalc_ps(local);
|
||||
ieee80211_recalc_ps_vif(sdata);
|
||||
+ ieee80211_check_fast_rx_iface(sdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3741,12 +3741,7 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
/* 4-addr is harder to deal with, later maybe */
|
||||
if (sdata->u.mgd.use_4addr)
|
||||
goto clear;
|
||||
- /* software powersave is a huge mess, avoid all of it */
|
||||
- if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
|
||||
- goto clear;
|
||||
- if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
|
||||
- !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
|
||||
- goto clear;
|
||||
+
|
||||
if (sta->sta.tdls) {
|
||||
fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
|
||||
fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
|
||||
@@ -3758,6 +3753,16 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
fastrx.expected_ds_bits =
|
||||
cpu_to_le16(IEEE80211_FCTL_FROMDS);
|
||||
}
|
||||
+
|
||||
+ if (!sdata->u.mgd.powersave)
|
||||
+ break;
|
||||
+
|
||||
+ /* software powersave is a huge mess, avoid all of it */
|
||||
+ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
|
||||
+ goto clear;
|
||||
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
|
||||
+ !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
|
||||
+ goto clear;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_AP:
|
|
@ -0,0 +1,34 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 23 Feb 2018 10:05:08 +0100
|
||||
Subject: [PATCH] mac80211: support station 4-addr mode fast-rx
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3738,10 +3738,6 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
- /* 4-addr is harder to deal with, later maybe */
|
||||
- if (sdata->u.mgd.use_4addr)
|
||||
- goto clear;
|
||||
-
|
||||
if (sta->sta.tdls) {
|
||||
fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1);
|
||||
fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2);
|
||||
@@ -3754,6 +3750,13 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
cpu_to_le16(IEEE80211_FCTL_FROMDS);
|
||||
}
|
||||
|
||||
+ if (sdata->u.mgd.use_4addr && !sta->sta.tdls) {
|
||||
+ fastrx.expected_ds_bits |=
|
||||
+ cpu_to_le16(IEEE80211_FCTL_TODS);
|
||||
+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3);
|
||||
+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4);
|
||||
+ }
|
||||
+
|
||||
if (!sdata->u.mgd.powersave)
|
||||
break;
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 26 Feb 2018 22:09:29 +0100
|
||||
Subject: [PATCH] mac80211: support A-MSDU in fast-rx
|
||||
|
||||
Only works if the IV was stripped from packets. Create a smaller
|
||||
variant of ieee80211_rx_h_amsdu, which bypasses checks already done
|
||||
within the fast-rx context.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2358,39 +2358,17 @@ ieee80211_deliver_skb(struct ieee80211_r
|
||||
}
|
||||
|
||||
static ieee80211_rx_result debug_noinline
|
||||
-ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
|
||||
+__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
|
||||
{
|
||||
struct net_device *dev = rx->sdata->dev;
|
||||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
struct sk_buff_head frame_list;
|
||||
- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
struct ethhdr ethhdr;
|
||||
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
|
||||
|
||||
- if (unlikely(!ieee80211_is_data(fc)))
|
||||
- return RX_CONTINUE;
|
||||
-
|
||||
- if (unlikely(!ieee80211_is_data_present(fc)))
|
||||
- return RX_DROP_MONITOR;
|
||||
-
|
||||
- if (!(status->rx_flags & IEEE80211_RX_AMSDU))
|
||||
- return RX_CONTINUE;
|
||||
-
|
||||
if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
|
||||
- switch (rx->sdata->vif.type) {
|
||||
- case NL80211_IFTYPE_AP_VLAN:
|
||||
- if (!rx->sdata->u.vlan.sta)
|
||||
- return RX_DROP_UNUSABLE;
|
||||
- break;
|
||||
- case NL80211_IFTYPE_STATION:
|
||||
- if (!rx->sdata->u.mgd.use_4addr)
|
||||
- return RX_DROP_UNUSABLE;
|
||||
- break;
|
||||
- default:
|
||||
- return RX_DROP_UNUSABLE;
|
||||
- }
|
||||
check_da = NULL;
|
||||
check_sa = NULL;
|
||||
} else switch (rx->sdata->vif.type) {
|
||||
@@ -2410,15 +2388,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
|
||||
break;
|
||||
}
|
||||
|
||||
- if (is_multicast_ether_addr(hdr->addr1))
|
||||
- return RX_DROP_UNUSABLE;
|
||||
-
|
||||
skb->dev = dev;
|
||||
__skb_queue_head_init(&frame_list);
|
||||
|
||||
if (ieee80211_data_to_8023_exthdr(skb, ðhdr,
|
||||
rx->sdata->vif.addr,
|
||||
- rx->sdata->vif.type))
|
||||
+ rx->sdata->vif.type,
|
||||
+ data_offset))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
|
||||
@@ -2440,6 +2416,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
+static ieee80211_rx_result debug_noinline
|
||||
+ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
|
||||
+{
|
||||
+ struct sk_buff *skb = rx->skb;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ __le16 fc = hdr->frame_control;
|
||||
+
|
||||
+ if (!(status->rx_flags & IEEE80211_RX_AMSDU))
|
||||
+ return RX_CONTINUE;
|
||||
+
|
||||
+ if (unlikely(!ieee80211_is_data(fc)))
|
||||
+ return RX_CONTINUE;
|
||||
+
|
||||
+ if (unlikely(!ieee80211_is_data_present(fc)))
|
||||
+ return RX_DROP_MONITOR;
|
||||
+
|
||||
+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
|
||||
+ switch (rx->sdata->vif.type) {
|
||||
+ case NL80211_IFTYPE_AP_VLAN:
|
||||
+ if (!rx->sdata->u.vlan.sta)
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+ break;
|
||||
+ case NL80211_IFTYPE_STATION:
|
||||
+ if (!rx->sdata->u.mgd.use_4addr)
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (is_multicast_ether_addr(hdr->addr1))
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+
|
||||
+ return __ieee80211_rx_h_amsdu(rx, 0);
|
||||
+}
|
||||
+
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
static ieee80211_rx_result
|
||||
ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
||||
@@ -3889,7 +3903,8 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
struct sta_info *sta = rx->sta;
|
||||
int orig_len = skb->len;
|
||||
- int snap_offs = ieee80211_hdrlen(hdr->frame_control);
|
||||
+ int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+ int snap_offs = hdrlen;
|
||||
struct {
|
||||
u8 snap[sizeof(rfc1042_header)];
|
||||
__be16 proto;
|
||||
@@ -3920,10 +3935,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
(status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS)
|
||||
return false;
|
||||
|
||||
- /* we don't deal with A-MSDU deaggregation here */
|
||||
- if (status->rx_flags & IEEE80211_RX_AMSDU)
|
||||
- return false;
|
||||
-
|
||||
if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
|
||||
return false;
|
||||
|
||||
@@ -3955,21 +3966,24 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
snap_offs += IEEE80211_CCMP_HDR_LEN;
|
||||
}
|
||||
|
||||
- if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
|
||||
- goto drop;
|
||||
- payload = (void *)(skb->data + snap_offs);
|
||||
+ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
|
||||
+ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
|
||||
+ goto drop;
|
||||
|
||||
- if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
|
||||
- return false;
|
||||
+ payload = (void *)(skb->data + snap_offs);
|
||||
|
||||
- /* Don't handle these here since they require special code.
|
||||
- * Accept AARP and IPX even though they should come with a
|
||||
- * bridge-tunnel header - but if we get them this way then
|
||||
- * there's little point in discarding them.
|
||||
- */
|
||||
- if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
|
||||
- payload->proto == fast_rx->control_port_protocol))
|
||||
- return false;
|
||||
+ if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Don't handle these here since they require special code.
|
||||
+ * Accept AARP and IPX even though they should come with a
|
||||
+ * bridge-tunnel header - but if we get them this way then
|
||||
+ * there's little point in discarding them.
|
||||
+ */
|
||||
+ if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) ||
|
||||
+ payload->proto == fast_rx->control_port_protocol))
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
/* after this point, don't punt to the slowpath! */
|
||||
|
||||
@@ -3983,12 +3997,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
}
|
||||
|
||||
/* statistics part of ieee80211_rx_h_sta_process() */
|
||||
- stats->last_rx = jiffies;
|
||||
- stats->last_rate = sta_stats_encode_rate(status);
|
||||
-
|
||||
- stats->fragments++;
|
||||
- stats->packets++;
|
||||
-
|
||||
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
|
||||
stats->last_signal = status->signal;
|
||||
if (!fast_rx->uses_rss)
|
||||
@@ -4017,6 +4025,20 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
if (rx->key && !ieee80211_has_protected(hdr->frame_control))
|
||||
goto drop;
|
||||
|
||||
+ if (status->rx_flags & IEEE80211_RX_AMSDU) {
|
||||
+ if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) !=
|
||||
+ RX_QUEUED)
|
||||
+ goto drop;
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ stats->last_rx = jiffies;
|
||||
+ stats->last_rate = sta_stats_encode_rate(status);
|
||||
+
|
||||
+ stats->fragments++;
|
||||
+ stats->packets++;
|
||||
+
|
||||
/* do the header conversion - first grab the addresses */
|
||||
ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
|
||||
ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -4331,10 +4331,12 @@ unsigned int ieee80211_get_mesh_hdrlen(s
|
||||
* of it being pushed into the SKB
|
||||
* @addr: the device MAC address
|
||||
* @iftype: the virtual interface type
|
||||
+ * @data_offset: offset of payload after the 802.11 header
|
||||
* Return: 0 on success. Non-zero on error.
|
||||
*/
|
||||
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
- const u8 *addr, enum nl80211_iftype iftype);
|
||||
+ const u8 *addr, enum nl80211_iftype iftype,
|
||||
+ u8 data_offset);
|
||||
|
||||
/**
|
||||
* ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
|
||||
@@ -4346,7 +4348,7 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
||||
enum nl80211_iftype iftype)
|
||||
{
|
||||
- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
|
||||
+ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -419,7 +419,8 @@ unsigned int ieee80211_get_mesh_hdrlen(s
|
||||
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
|
||||
|
||||
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
- const u8 *addr, enum nl80211_iftype iftype)
|
||||
+ const u8 *addr, enum nl80211_iftype iftype,
|
||||
+ u8 data_offset)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct {
|
||||
@@ -433,7 +434,7 @@ int ieee80211_data_to_8023_exthdr(struct
|
||||
if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
|
||||
return -1;
|
||||
|
||||
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
+ hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset;
|
||||
if (skb->len < hdrlen + 8)
|
||||
return -1;
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
From 5242a5444e0b6464d7455beb55d936dd192b5e9d Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 22 Jan 2018 21:46:39 +0100
|
||||
Subject: [PATCH] brcmfmac: assure bcdc dcmd api does not return value > 0
|
||||
|
||||
The protocol layer api defines callbacks for dongle commands.
|
||||
Although not really well documented these should only return an
|
||||
error code in case of an error, or 0 upon success. In the bcdc
|
||||
protocol it can return value above 0 and we carry a fix in the
|
||||
caller of the protocol layer api. This patch makes it adhere to
|
||||
the intent of the api as described above.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 6 +++++-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 8 +++-----
|
||||
2 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -211,6 +211,8 @@ retry:
|
||||
memcpy(buf, info, len);
|
||||
}
|
||||
|
||||
+ ret = 0;
|
||||
+
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
@@ -225,7 +227,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
|
||||
- int ret = 0;
|
||||
+ int ret;
|
||||
u32 flags, id;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
@@ -249,6 +251,8 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ ret = 0;
|
||||
+
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
@@ -121,11 +121,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp,
|
||||
else
|
||||
err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
|
||||
|
||||
- if (err >= 0)
|
||||
- return 0;
|
||||
-
|
||||
- brcmf_dbg(FIL, "Failed: %s (%d)\n",
|
||||
- brcmf_fil_get_errstr((u32)(-err)), err);
|
||||
+ if (err)
|
||||
+ brcmf_dbg(FIL, "Failed: %s (%d)\n",
|
||||
+ brcmf_fil_get_errstr((u32)(-err)), err);
|
||||
|
||||
return err;
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
From b69c1df47281ad47bd2037a42b98f5c7115b7fd5 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 22 Jan 2018 21:46:40 +0100
|
||||
Subject: [PATCH] brcmfmac: separate firmware errors from i/o errors
|
||||
|
||||
When using the firmware api it can fail simply because firmware does
|
||||
not like the request or it fails due to issues in the host interface.
|
||||
Currently, there is only a single error code which is confusing. So
|
||||
adding a parameter to pass the firmware error separately and in case
|
||||
of a firmware error always return -EBADE to user-space.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 11 ++++++-----
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 16 +++++++++++-----
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 10 ++++++----
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 14 ++++++++------
|
||||
4 files changed, 31 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -165,7 +165,7 @@ static int brcmf_proto_bcdc_cmplt(struct
|
||||
|
||||
static int
|
||||
brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
- void *buf, uint len)
|
||||
+ void *buf, uint len, int *fwerr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
|
||||
@@ -175,6 +175,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf
|
||||
|
||||
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
+ *fwerr = 0;
|
||||
ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
|
||||
if (ret < 0) {
|
||||
brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
|
||||
@@ -215,15 +216,14 @@ retry:
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
- ret = le32_to_cpu(msg->status);
|
||||
-
|
||||
+ *fwerr = le32_to_cpu(msg->status);
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
- void *buf, uint len)
|
||||
+ void *buf, uint len, int *fwerr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
|
||||
@@ -232,6 +232,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p
|
||||
|
||||
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
+ *fwerr = 0;
|
||||
ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
@@ -255,7 +256,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
- ret = le32_to_cpu(msg->status);
|
||||
+ *fwerr = le32_to_cpu(msg->status);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
@@ -107,7 +107,7 @@ static s32
|
||||
brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
|
||||
{
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
- s32 err;
|
||||
+ s32 err, fwerr;
|
||||
|
||||
if (drvr->bus_if->state != BRCMF_BUS_UP) {
|
||||
brcmf_err("bus is down. we have nothing to do.\n");
|
||||
@@ -117,14 +117,20 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp,
|
||||
if (data != NULL)
|
||||
len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
|
||||
if (set)
|
||||
- err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
|
||||
+ err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd,
|
||||
+ data, len, &fwerr);
|
||||
else
|
||||
- err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
|
||||
+ err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd,
|
||||
+ data, len, &fwerr);
|
||||
|
||||
- if (err)
|
||||
+ if (err) {
|
||||
brcmf_dbg(FIL, "Failed: %s (%d)\n",
|
||||
brcmf_fil_get_errstr((u32)(-err)), err);
|
||||
-
|
||||
+ } else if (fwerr < 0) {
|
||||
+ brcmf_dbg(FIL, "Firmware error: %s (%d)\n",
|
||||
+ brcmf_fil_get_errstr((u32)(-fwerr)), fwerr);
|
||||
+ err = -EBADE;
|
||||
+ }
|
||||
return err;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -477,7 +477,7 @@ static void brcmf_msgbuf_ioctl_resp_wake
|
||||
|
||||
|
||||
static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
- uint cmd, void *buf, uint len)
|
||||
+ uint cmd, void *buf, uint len, int *fwerr)
|
||||
{
|
||||
struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
|
||||
struct sk_buff *skb = NULL;
|
||||
@@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struc
|
||||
int err;
|
||||
|
||||
brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
|
||||
+ *fwerr = 0;
|
||||
msgbuf->ctl_completed = false;
|
||||
err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
|
||||
if (err)
|
||||
@@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struc
|
||||
}
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
|
||||
- return msgbuf->ioctl_resp_status;
|
||||
+ *fwerr = msgbuf->ioctl_resp_status;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
- uint cmd, void *buf, uint len)
|
||||
+ uint cmd, void *buf, uint len, int *fwerr)
|
||||
{
|
||||
- return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len);
|
||||
+ return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
|
||||
}
|
||||
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
@@ -30,9 +30,9 @@ struct brcmf_proto {
|
||||
int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
|
||||
struct sk_buff *skb, struct brcmf_if **ifp);
|
||||
int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
- void *buf, uint len);
|
||||
+ void *buf, uint len, int *fwerr);
|
||||
int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
|
||||
- uint len);
|
||||
+ uint len, int *fwerr);
|
||||
int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx,
|
||||
struct sk_buff *skb);
|
||||
int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
|
||||
@@ -71,14 +71,16 @@ static inline int brcmf_proto_hdrpull(st
|
||||
return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
|
||||
}
|
||||
static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
- uint cmd, void *buf, uint len)
|
||||
+ uint cmd, void *buf, uint len,
|
||||
+ int *fwerr)
|
||||
{
|
||||
- return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
|
||||
+ return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len,fwerr);
|
||||
}
|
||||
static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
- uint cmd, void *buf, uint len)
|
||||
+ uint cmd, void *buf, uint len,
|
||||
+ int *fwerr)
|
||||
{
|
||||
- return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
|
||||
+ return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
|
||||
}
|
||||
|
||||
static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx,
|
|
@ -0,0 +1,92 @@
|
|||
From 933897342d0714ae1c10729cbaeecea0c6178db5 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 28 Feb 2018 21:15:19 +0100
|
||||
Subject: [PATCH] brcmfmac: add possibility to obtain firmware error
|
||||
|
||||
The feature module needs to evaluate the actual firmware error return
|
||||
upon a control command. This adds a flag to struct brcmf_if that the
|
||||
caller can set. This flag is checked to determine the error code that
|
||||
needs to be returned.
|
||||
|
||||
Fixes: b69c1df47281 ("brcmfmac: separate firmware errors from i/o errors")
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 2 ++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 10 ++++++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 3 +++
|
||||
3 files changed, 15 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -181,6 +181,7 @@ enum brcmf_netif_stop_reason {
|
||||
* @netif_stop_lock: spinlock for update netif_stop from multiple sources.
|
||||
* @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
|
||||
* @pend_8021x_wait: used for signalling change in count.
|
||||
+ * @fwil_fwerr: flag indicating fwil layer should return firmware error codes.
|
||||
*/
|
||||
struct brcmf_if {
|
||||
struct brcmf_pub *drvr;
|
||||
@@ -198,6 +199,7 @@ struct brcmf_if {
|
||||
wait_queue_head_t pend_8021x_wait;
|
||||
struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
|
||||
u8 ipv6addr_idx;
|
||||
+ bool fwil_fwerr;
|
||||
};
|
||||
|
||||
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -104,6 +104,9 @@ static void brcmf_feat_iovar_int_get(str
|
||||
u32 data;
|
||||
int err;
|
||||
|
||||
+ /* we need to know firmware error */
|
||||
+ ifp->fwil_fwerr = true;
|
||||
+
|
||||
err = brcmf_fil_iovar_int_get(ifp, name, &data);
|
||||
if (err == 0) {
|
||||
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
|
||||
@@ -112,6 +115,8 @@ static void brcmf_feat_iovar_int_get(str
|
||||
brcmf_dbg(TRACE, "%s feature check failed: %d\n",
|
||||
brcmf_feat_names[id], err);
|
||||
}
|
||||
+
|
||||
+ ifp->fwil_fwerr = false;
|
||||
}
|
||||
|
||||
static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
|
||||
@@ -120,6 +125,9 @@ static void brcmf_feat_iovar_data_set(st
|
||||
{
|
||||
int err;
|
||||
|
||||
+ /* we need to know firmware error */
|
||||
+ ifp->fwil_fwerr = true;
|
||||
+
|
||||
err = brcmf_fil_iovar_data_set(ifp, name, data, len);
|
||||
if (err != -BRCMF_FW_UNSUPPORTED) {
|
||||
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
|
||||
@@ -128,6 +136,8 @@ static void brcmf_feat_iovar_data_set(st
|
||||
brcmf_dbg(TRACE, "%s feature check failed: %d\n",
|
||||
brcmf_feat_names[id], err);
|
||||
}
|
||||
+
|
||||
+ ifp->fwil_fwerr = false;
|
||||
}
|
||||
|
||||
#define MAX_CAPS_BUFFER_SIZE 512
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
|
||||
@@ -131,6 +131,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp,
|
||||
brcmf_fil_get_errstr((u32)(-fwerr)), fwerr);
|
||||
err = -EBADE;
|
||||
}
|
||||
+ if (ifp->fwil_fwerr)
|
||||
+ return fwerr;
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
From 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Wed, 28 Feb 2018 21:15:20 +0100
|
||||
Subject: [PATCH] brcmfmac: fix P2P_DEVICE ethernet address generation
|
||||
|
||||
The firmware has a requirement that the P2P_DEVICE address should
|
||||
be different from the address of the primary interface. When not
|
||||
specified by user-space, the driver generates the MAC address for
|
||||
the P2P_DEVICE interface using the MAC address of the primary
|
||||
interface and setting the locally administered bit. However, the MAC
|
||||
address of the primary interface may already have that bit set causing
|
||||
the creation of the P2P_DEVICE interface to fail with -EBUSY. Fix this
|
||||
by using a random address instead to determine the P2P_DEVICE address.
|
||||
|
||||
Cc: stable@vger.kernel.org # 3.10.y
|
||||
Reported-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 24 ++++++++++------------
|
||||
1 file changed, 11 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct
|
||||
* @dev_addr: optional device address.
|
||||
*
|
||||
* P2P needs mac addresses for P2P device and interface. If no device
|
||||
- * address it specified, these are derived from the primary net device, ie.
|
||||
- * the permanent ethernet address of the device.
|
||||
+ * address it specified, these are derived from a random ethernet
|
||||
+ * address.
|
||||
*/
|
||||
static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
|
||||
{
|
||||
- struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
|
||||
- bool local_admin = false;
|
||||
+ bool random_addr = false;
|
||||
|
||||
- if (!dev_addr || is_zero_ether_addr(dev_addr)) {
|
||||
- dev_addr = pri_ifp->mac_addr;
|
||||
- local_admin = true;
|
||||
- }
|
||||
+ if (!dev_addr || is_zero_ether_addr(dev_addr))
|
||||
+ random_addr = true;
|
||||
|
||||
- /* Generate the P2P Device Address. This consists of the device's
|
||||
- * primary MAC address with the locally administered bit set.
|
||||
+ /* Generate the P2P Device Address obtaining a random ethernet
|
||||
+ * address with the locally administered bit set.
|
||||
*/
|
||||
- memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
|
||||
- if (local_admin)
|
||||
- p2p->dev_addr[0] |= 0x02;
|
||||
+ if (random_addr)
|
||||
+ eth_random_addr(p2p->dev_addr);
|
||||
+ else
|
||||
+ memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
|
||||
|
||||
/* Generate the P2P Interface Address. If the discovery and connection
|
||||
* BSSCFGs need to simultaneously co-exist, then this address must be
|
|
@ -0,0 +1,157 @@
|
|||
From 1259055170287a350cad453e9eac139c81609860 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 15 Mar 2018 08:29:09 +0100
|
||||
Subject: [PATCH] brcmfmac: drop Inter-Access Point Protocol packets by default
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Testing brcmfmac with more recent firmwares resulted in AP interfaces
|
||||
not working in some specific setups. Debugging resulted in discovering
|
||||
support for IAPP in Broadcom's firmwares.
|
||||
|
||||
Older firmwares were only generating 802.11f frames. Newer ones like:
|
||||
1) 10.10 (TOB) (r663589)
|
||||
2) 10.10.122.20 (r683106)
|
||||
for 4366b1 and 4366c0 respectively seem to also /respect/ 802.11f frames
|
||||
in the Tx path by performing a STA disassociation.
|
||||
|
||||
This obsoleted standard and its implementation is something that:
|
||||
1) Most people don't need / want to use
|
||||
2) Can allow local DoS attacks
|
||||
3) Breaks AP interfaces in some specific bridge setups
|
||||
|
||||
To solve issues it can cause this commit modifies brcmfmac to drop IAPP
|
||||
packets. If affects:
|
||||
1) Rx path: driver won't be sending these unwanted packets up.
|
||||
2) Tx path: driver will reject packets that would trigger STA
|
||||
disassociation perfromed by a firmware (possible local DoS attack).
|
||||
|
||||
It appears there are some Broadcom's clients/users who care about this
|
||||
feature despite the drawbacks. They can switch it on using a new module
|
||||
param.
|
||||
|
||||
This change results in only two more comparisons (check for module param
|
||||
and check for Ethernet packet length) for 99.9% of packets. Its overhead
|
||||
should be very minimal.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 5 ++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 1 +
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 57 ++++++++++++++++++++++
|
||||
3 files changed, 63 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -75,6 +75,10 @@ static int brcmf_roamoff;
|
||||
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
|
||||
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
|
||||
|
||||
+static int brcmf_iapp_enable;
|
||||
+module_param_named(iapp, brcmf_iapp_enable, int, 0);
|
||||
+MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
|
||||
+
|
||||
#ifdef DEBUG
|
||||
/* always succeed brcmf_bus_started() */
|
||||
static int brcmf_ignore_probe_fail;
|
||||
@@ -441,6 +445,7 @@ struct brcmf_mp_device *brcmf_get_module
|
||||
settings->feature_disable = brcmf_feature_disable;
|
||||
settings->fcmode = brcmf_fcmode;
|
||||
settings->roamoff = !!brcmf_roamoff;
|
||||
+ settings->iapp = !!brcmf_iapp_enable;
|
||||
#ifdef DEBUG
|
||||
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
|
||||
#endif
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -58,6 +58,7 @@ struct brcmf_mp_device {
|
||||
unsigned int feature_disable;
|
||||
int fcmode;
|
||||
bool roamoff;
|
||||
+ bool iapp;
|
||||
bool ignore_probe_fail;
|
||||
struct brcmfmac_pd_cc *country_codes;
|
||||
union {
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_l
|
||||
schedule_work(&ifp->multicast_work);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * brcmf_skb_is_iapp - checks if skb is an IAPP packet
|
||||
+ *
|
||||
+ * @skb: skb to check
|
||||
+ */
|
||||
+static bool brcmf_skb_is_iapp(struct sk_buff *skb)
|
||||
+{
|
||||
+ static const u8 iapp_l2_update_packet[6] __aligned(2) = {
|
||||
+ 0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
|
||||
+ };
|
||||
+ unsigned char *eth_data;
|
||||
+#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
+ const u16 *a, *b;
|
||||
+#endif
|
||||
+
|
||||
+ if (skb->len - skb->mac_len != 6 ||
|
||||
+ !is_multicast_ether_addr(eth_hdr(skb)->h_dest))
|
||||
+ return false;
|
||||
+
|
||||
+ eth_data = skb_mac_header(skb) + ETH_HLEN;
|
||||
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
+ return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) |
|
||||
+ ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4))));
|
||||
+#else
|
||||
+ a = (const u16 *)eth_data;
|
||||
+ b = (const u16 *)iapp_l2_update_packet;
|
||||
+
|
||||
+ return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *ndev)
|
||||
{
|
||||
@@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xm
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ /* Some recent Broadcom's firmwares disassociate STA when they receive
|
||||
+ * an 802.11f ADD frame. This behavior can lead to a local DoS security
|
||||
+ * issue. Attacker may trigger disassociation of any STA by sending a
|
||||
+ * proper Ethernet frame to the wireless interface.
|
||||
+ *
|
||||
+ * Moreover this feature may break AP interfaces in some specific
|
||||
+ * setups. This applies e.g. to the bridge with hairpin mode enabled and
|
||||
+ * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware
|
||||
+ * will get passed back to the wireless interface and cause immediate
|
||||
+ * disassociation of a just-connected STA.
|
||||
+ */
|
||||
+ if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
|
||||
+ dev_kfree_skb(skb);
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
/* Make sure there's enough writeable headroom */
|
||||
if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {
|
||||
head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);
|
||||
@@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
{
|
||||
+ /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
|
||||
+ * STA connects to the AP interface. This is an obsoleted standard most
|
||||
+ * users don't use, so don't pass these frames up unless requested.
|
||||
+ */
|
||||
+ if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
|
||||
+ brcmu_pkt_buf_free_skb(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (skb->pkt_type == PACKET_MULTICAST)
|
||||
ifp->ndev->stats.multicast++;
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
From 9b9322db5c5a1917a66c71fe47c3848a9a31227e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Date: Wed, 14 Mar 2018 20:02:59 +0100
|
||||
Subject: [PATCH] brcmfmac: Fix check for ISO3166 code
|
||||
|
||||
The commit "regulatory: add NUL to request alpha2" increases the length of
|
||||
alpha2 to 3. This causes a regression on brcmfmac, because
|
||||
brcmf_cfg80211_reg_notifier() expect valid ISO3166 codes in the complete
|
||||
array. So fix this accordingly.
|
||||
|
||||
Fixes: 657308f73e67 ("regulatory: add NUL to request alpha2")
|
||||
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Acked-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6803,7 +6803,7 @@ static void brcmf_cfg80211_reg_notifier(
|
||||
return;
|
||||
|
||||
/* ignore non-ISO3166 country codes */
|
||||
- for (i = 0; i < sizeof(req->alpha2); i++)
|
||||
+ for (i = 0; i < 2; i++)
|
||||
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
|
||||
brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n",
|
||||
req->alpha2[0], req->alpha2[1]);
|
|
@ -0,0 +1,45 @@
|
|||
From da472385a29f1fddcac7cfa0499482704310bd16 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Tue, 20 Feb 2018 00:14:18 +0100
|
||||
Subject: [PATCH] brcmfmac: move brcmf_bus_preinit() call just after changing
|
||||
bus state
|
||||
|
||||
Moving the brcmf_bus_preinit() call allows the bus code to do some
|
||||
required initialization before handling firmware control messages.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 3 ---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -369,9 +369,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
|
||||
|
||||
/* Enable tx beamforming, errors can be ignored (not supported) */
|
||||
(void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
|
||||
-
|
||||
- /* do bus specific preinit here */
|
||||
- err = brcmf_bus_preinit(ifp->drvr->bus_if);
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1091,6 +1091,11 @@ int brcmf_bus_started(struct device *dev
|
||||
/* signal bus ready */
|
||||
brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);
|
||||
|
||||
+ /* do bus specific preinit here */
|
||||
+ ret = brcmf_bus_preinit(ifp->drvr->bus_if);
|
||||
+ if (ret < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
/* Bus is ready, do any initialization */
|
||||
ret = brcmf_c_preinit_dcmds(ifp);
|
||||
if (ret < 0)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue