1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709 |
- commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0
- Author: Felix Fietkau <[email protected]>
- Date: Fri Feb 28 18:52:56 2014 +0100
- ath9k_hw: tweak noise immunity thresholds for older chipsets
-
- Older chipsets are more sensitive to high PHY error counts, and the
- current noise immunity thresholds were based on tests run at QCA with
- newer chipsets.
-
- This patch brings back the values from the old ANI implementation for
- old chipsets, and it also disables weak signal detection on an earlier
- noise immunity level, to improve overall radio stability on affected
- devices.
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit 431e506da5953adc3b65af25f4b90873d528c115
- Author: Felix Fietkau <[email protected]>
- Date: Fri Feb 28 18:44:13 2014 +0100
- ath9k_hw: toggle weak signal detection in AP mode on older chipsets
-
- The commit 80b4205b "ath9k: Fix OFDM weak signal detection for AP mode"
- prevented weak signal detection changes from taking effect in AP mode on
- all chipsets, claiming it is "not allowed".
-
- The main reason for not disabling weak signal detection in AP mode is
- that typically beacon RSSI is used to track whether it is needed to
- boost range, and this is unavailable in AP mode for obvious reasons.
-
- The problem with not disabling weak signal detection is that older
- chipsets are very sensitive to high PHY error counts. When faced with
- heavy noise, this can lead to an excessive amount of "Failed to stop
- TX DMA" errors in the field.
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit 98d1a6c5b14688ed030e81b889f607be308e0df9
- Author: Felix Fietkau <[email protected]>
- Date: Mon Feb 24 22:20:32 2014 +0100
- ath9k: fix invalid descriptor discarding
-
- Only set sc->rx.discard_next to rx_stats->rs_more when actually
- discarding the current descriptor.
-
- Also, fix a detection of broken descriptors:
- First the code checks if the current descriptor is not done.
- Then it checks if the next descriptor is done.
- Add a check that afterwards checks the first descriptor again, because
- it might have been completed in the mean time.
-
- This fixes a regression introduced in
- commit 723e711356b5a8a95728a890e254e8b0d47b55cf
- "ath9k: fix handling of broken descriptors"
-
- Cc: [email protected]
- Reported-by: Marco André Dinis <[email protected]>
- Signed-off-by: Felix Fietkau <[email protected]>
- commit 52a46300e782fe6994466523eb2b0b59091ea59f
- Author: Felix Fietkau <[email protected]>
- Date: Mon Feb 24 11:43:50 2014 +0100
- ath9k: reduce baseband hang detection false positive rate
-
- Check if the baseband state remains stable, and add a small delay
- between register reads.
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit 118945bb12082e9d4edddc868d88143164e0f440
- Author: Felix Fietkau <[email protected]>
- Date: Sat Feb 22 14:55:23 2014 +0100
- ath5k: set SURVEY_INFO_IN_USE on get_survey
-
- Only one channel is returned - the one currently being used.
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit ee41f72476e1ea44283dfe1cbf75b9543a1e15c8
- Author: Felix Fietkau <[email protected]>
- Date: Sat Feb 22 14:44:52 2014 +0100
- ath9k: make some hardware reset log messages debug-only
-
- On some chips, baseband watchdog hangs are more common than others, and
- the driver has support for handling them.
- Interrupts even after a watchdog hang are also quite common, so there's
- not much point in spamming the user's logfiles.
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit b14fbb554fc65a2e0b5c41a319269b0350f187e7
- Author: Felix Fietkau <[email protected]>
- Date: Sat Feb 22 14:35:25 2014 +0100
- ath9k: do not set half/quarter channel flags in AR_PHY_MODE
-
- 5/10 MHz channel bandwidth is configured via the PLL clock, instead of
- the AR_PHY_MODE register. Using that register is AR93xx specific, and
- makes the mode incompatible with earlier chipsets.
-
- In some early versions, these flags were apparently applied at the wrong
- point in time and thus did not cause connectivity issues, however now
- they are causing problems, as pointed out in this OpenWrt ticket:
-
- https://dev.openwrt.org/ticket/14916
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit 0f1cb7be2551b30b02cd54c897e0e29e483cfda5
- Author: Felix Fietkau <[email protected]>
- Date: Sat Feb 22 13:43:29 2014 +0100
- ath9k: fix ps-poll responses under a-mpdu sessions
-
- When passing tx frames to the U-APSD queue for powersave poll responses,
- the ath_atx_tid pointer needs to be passed to ath_tx_setup_buffer for
- proper sequence number accounting.
-
- This fixes high latency and connection stability issues with ath9k
- running as AP and a few kinds of mobile phones as client, when PS-Poll
- is heavily used
-
- Cc: [email protected]
- Signed-off-by: Felix Fietkau <[email protected]>
- commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5
- Author: Felix Fietkau <[email protected]>
- Date: Fri Feb 21 11:39:59 2014 +0100
- ath9k: list more reset causes in debugfs
-
- Number of MAC hangs and stuck beacons were missing
-
- Signed-off-by: Felix Fietkau <[email protected]>
- commit d84856012e0f10fe598a5ad3b7b869397a089e07
- Author: Johannes Berg <[email protected]>
- Date: Thu Feb 20 11:19:58 2014 +0100
- mac80211: fix station wakeup powersave race
-
- Consider the following (relatively unlikely) scenario:
- 1) station goes to sleep while frames are buffered in driver
- 2) driver blocks wakeup (until no more frames are buffered)
- 3) station wakes up again
- 4) driver unblocks wakeup
-
- In this case, the current mac80211 code will do the following:
- 1) WLAN_STA_PS_STA set
- 2) WLAN_STA_PS_DRIVER set
- 3) - nothing -
- 4) WLAN_STA_PS_DRIVER cleared
-
- As a result, no frames will be delivered to the client, even
- though it is awake, until it sends another frame to us that
- triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end().
-
- Since we now take the PS spinlock, we can fix this while at
- the same time removing the complexity with the pending skb
- queue function. This was broken since my commit 50a9432daeec
- ("mac80211: fix powersaving clients races") due to removing
- the clearing of WLAN_STA_PS_STA in the RX path.
-
- While at it, fix a cleanup path issue when a station is
- removed while the driver is still blocking its wakeup.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit 798f2786602cbe93e6b928299614aa36ebf50692
- Author: Johannes Berg <[email protected]>
- Date: Mon Feb 17 20:49:03 2014 +0100
- mac80211: insert stations before adding to driver
-
- There's a race condition in mac80211 because we add stations
- to the internal lists after adding them to the driver, which
- means that (for example) the following can happen:
- 1. a station connects and is added
- 2. first, it is added to the driver
- 3. then, it is added to the mac80211 lists
-
- If the station goes to sleep between steps 2 and 3, and the
- firmware/hardware records it as being asleep, mac80211 will
- never instruct the driver to wake it up again as it never
- realized it went to sleep since the RX path discarded the
- frame as a "spurious class 3 frame", no station entry was
- present yet.
-
- Fix this by adding the station in software first, and only
- then adding it to the driver. That way, any state that the
- driver changes will be reflected properly in mac80211's
- station state. The problematic part is the roll-back if the
- driver fails to add the station, in that case a bit more is
- needed. To not make that overly complex prevent starting BA
- sessions in the meantime.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe
- Author: Emmanuel Grumbach <[email protected]>
- Date: Thu Feb 20 09:22:11 2014 +0200
- mac80211: fix AP powersave TX vs. wakeup race
-
- There is a race between the TX path and the STA wakeup: while
- a station is sleeping, mac80211 buffers frames until it wakes
- up, then the frames are transmitted. However, the RX and TX
- path are concurrent, so the packet indicating wakeup can be
- processed while a packet is being transmitted.
-
- This can lead to a situation where the buffered frames list
- is emptied on the one side, while a frame is being added on
- the other side, as the station is still seen as sleeping in
- the TX path.
-
- As a result, the newly added frame will not be send anytime
- soon. It might be sent much later (and out of order) when the
- station goes to sleep and wakes up the next time.
-
- Additionally, it can lead to the crash below.
-
- Fix all this by synchronising both paths with a new lock.
- Both path are not fastpath since they handle PS situations.
-
- In a later patch we'll remove the extra skb queue locks to
- reduce locking overhead.
-
- BUG: unable to handle kernel
- NULL pointer dereference at 000000b0
- IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
- *pde = 00000000
- Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
- EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
- EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
- EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
- ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
- DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
- CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
- DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
- DR6: ffff0ff0 DR7: 00000400
- Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
- iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
- Stack:
- e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
- ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
- ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
- Call Trace:
- [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
- [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
- [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
- [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
- [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
- [<c149ef70>] dev_hard_start_xmit+0x450/0x950
- [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
- [<c14b9c9b>] __qdisc_run+0x4b/0x150
- [<c149f732>] dev_queue_xmit+0x2c2/0xca0
-
- Cc: [email protected]
- Reported-by: Yaara Rozenblum <[email protected]>
- Signed-off-by: Emmanuel Grumbach <[email protected]>
- Reviewed-by: Stanislaw Gruszka <[email protected]>
- [reword commit log, use a separate lock]
- Signed-off-by: Johannes Berg <[email protected]>
- commit 80e419de0dff38436b30d363311c625766193f86
- Author: Inbal Hacohen <[email protected]>
- Date: Wed Feb 12 09:32:27 2014 +0200
- cfg80211: bugfix in regulatory user hint process
-
- After processing hint_user, we would want to schedule the
- timeout work only if we are actually waiting to CRDA. This happens
- when the status is not "IGNORE" nor "ALREADY_SET".
-
- Signed-off-by: Inbal Hacohen <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit 6514c93afede55284e2cb63359aadedb85884c80
- Author: Jouni Malinen <[email protected]>
- Date: Tue Feb 18 20:41:08 2014 +0200
- ath9k: Enable U-APSD AP mode support
-
- mac80211 handles the actual operations, so ath9k can just indicate
- support for this. Based on initial tests, this combination seems to
- work fine.
-
- Signed-off-by: Jouni Malinen <[email protected]>
- commit a63caf0a357ad5c1f08d6b7827dc76c451445017
- Author: Stanislaw Gruszka <[email protected]>
- Date: Wed Feb 19 13:15:17 2014 +0100
- ath9k: protect tid->sched check
-
- We check tid->sched without a lock taken on ath_tx_aggr_sleep(). That
- is race condition which can result of doing list_del(&tid->list) twice
- (second time with poisoned list node) and cause crash like shown below:
-
- [424271.637220] BUG: unable to handle kernel paging request at 00100104
- [424271.637328] IP: [<f90fc072>] ath_tx_aggr_sleep+0x62/0xe0 [ath9k]
- ...
- [424271.639953] Call Trace:
- [424271.639998] [<f90f6900>] ? ath9k_get_survey+0x110/0x110 [ath9k]
- [424271.640083] [<f90f6942>] ath9k_sta_notify+0x42/0x50 [ath9k]
- [424271.640177] [<f809cfef>] sta_ps_start+0x8f/0x1c0 [mac80211]
- [424271.640258] [<c10f730e>] ? free_compound_page+0x2e/0x40
- [424271.640346] [<f809e915>] ieee80211_rx_handlers+0x9d5/0x2340 [mac80211]
- [424271.640437] [<c112f048>] ? kmem_cache_free+0x1d8/0x1f0
- [424271.640510] [<c1345a84>] ? kfree_skbmem+0x34/0x90
- [424271.640578] [<c10fc23c>] ? put_page+0x2c/0x40
- [424271.640640] [<c1345a84>] ? kfree_skbmem+0x34/0x90
- [424271.640706] [<c1345a84>] ? kfree_skbmem+0x34/0x90
- [424271.640787] [<f809dde3>] ? ieee80211_rx_handlers_result+0x73/0x1d0 [mac80211]
- [424271.640897] [<f80a07a0>] ieee80211_prepare_and_rx_handle+0x520/0xad0 [mac80211]
- [424271.641009] [<f809e22d>] ? ieee80211_rx_handlers+0x2ed/0x2340 [mac80211]
- [424271.641104] [<c13846ce>] ? ip_output+0x7e/0xd0
- [424271.641182] [<f80a1057>] ieee80211_rx+0x307/0x7c0 [mac80211]
- [424271.641266] [<f90fa6ee>] ath_rx_tasklet+0x88e/0xf70 [ath9k]
- [424271.641358] [<f80a0f2c>] ? ieee80211_rx+0x1dc/0x7c0 [mac80211]
- [424271.641445] [<f90f82db>] ath9k_tasklet+0xcb/0x130 [ath9k]
-
- Bug report:
- https://bugzilla.kernel.org/show_bug.cgi?id=70551
-
- Reported-and-tested-by: Max Sydorenko <[email protected]>
- Cc: [email protected]
- Signed-off-by: Stanislaw Gruszka <[email protected]>
- commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41
- Author: Felix Fietkau <[email protected]>
- Date: Tue Feb 11 15:54:13 2014 +0100
- mac80211: send control port protocol frames to the VO queue
-
- Improves reliability of wifi connections with WPA, since authentication
- frames are prioritized over normal traffic and also typically exempt
- from aggregation.
-
- Cc: [email protected]
- Signed-off-by: Felix Fietkau <[email protected]>
- commit d4426800f71e972feaa33e04c5801fc730627bdd
- Author: Stanislaw Gruszka <[email protected]>
- Date: Mon Feb 10 22:38:28 2014 +0100
- rtl8187: fix regression on MIPS without coherent DMA
-
- This patch fixes regression caused by commit a16dad77634 "MIPS: Fix
- potencial corruption". That commit fixes one corruption scenario in
- cost of adding another one, which actually start to cause crashes
- on Yeeloong laptop when rtl8187 driver is used.
-
- For correct DMA read operation on machines without DMA coherence, kernel
- have to invalidate cache, such it will refill later with new data that
- device wrote to memory, when that data is needed to process. We can only
- invalidate full cache line. Hence when cache line includes both dma
- buffer and some other data (written in cache, but not yet in main
- memory), the other data can not hit memory due to invalidation. That
- happen on rtl8187 where struct rtl8187_priv fields are located just
- before and after small buffers that are passed to USB layer and DMA
- is performed on them.
-
- To fix the problem we align buffers and reserve space after them to make
- them match cache line.
-
- This patch does not resolve all possible MIPS problems entirely, for
- that we have to assure that we always map cache aligned buffers for DMA,
- what can be complex or even not possible. But patch fixes visible and
- reproducible regression and seems other possible corruptions do not
- happen in practice, since Yeeloong laptop works stable without rtl8187
- driver.
-
- Bug report:
- https://bugzilla.kernel.org/show_bug.cgi?id=54391
-
- Reported-by: Petr Pisar <[email protected]>
- Bisected-by: Tom Li <[email protected]>
- Reported-and-tested-by: Tom Li <[email protected]>
- Cc: [email protected]
- Signed-off-by: Stanislaw Gruszka <[email protected]>
- commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:55 2014 +0530
- ath9k: Calculate IQ-CAL median
-
- This patch adds a routine to calculate the median IQ correction
- values for AR955x, which is used for outlier detection.
- The normal method which is used for all other chips is
- bypassed for AR955x.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit c52a6fce0820c8d0687443ab86058ae03b478c8f
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:54 2014 +0530
- ath9k: Expand the IQ coefficient array
-
- This will be used for storing data for mutiple
- IQ calibration runs, for AR955x.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit 034969ff5c2b6431d10e07c1938f0b916da85cc3
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:53 2014 +0530
- ath9k: Modify IQ calibration for AR955x
-
- IQ calibration post-processing for AR955x is different
- from other chips - instead of just doing it as part
- of AGC calibration once, it is triggered 3 times and
- a median is determined. This patch adds initial support
- for changing the calibration behavior for AR955x.
-
- Also, to simplify things, a helper routine to issue/poll
- AGC calibration is used.
-
- For non-AR955x chips, the iqcal_idx (which will be used
- in subsequent patches) is set to zero.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:52 2014 +0530
- ath9k: Fix magnitude/phase calculation
-
- Incorrect values are programmed in the registers
- containing the IQ correction coefficients by the IQ-CAL
- post-processing code. Fix this.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit 36f93484f96f79171dcecb67c5ef0c3de22531a6
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:51 2014 +0530
- ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes
-
- Use ar9003_hw_tx_iq_cal_outlier_detection instead.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit 3af09a7f5d21dd5fd15b973ce6a91a575da30417
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:50 2014 +0530
- ath9k: Check explicitly for IQ calibration
-
- In chips like AR955x, the initvals contain the information
- whether IQ calibration is to be done in the HW when an
- AGC calibration is triggered. Check if IQ-CAL is enabled
- in the initvals before flagging 'txiqcal_done' as true.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit cb4969634b93c4643a32cc3fbd27d2b288b25771
- Author: Sujith Manoharan <[email protected]>
- Date: Fri Feb 7 10:29:49 2014 +0530
- ath9k: Fix IQ cal post processing for SoC
-
- Calibration data is not reused for SoC chips, so
- call ar9003_hw_tx_iq_cal_post_proc() with the correct
- argument. The 'is_reusable' flag is currently used
- only for PC-OEM chips, but it makes things clearer to
- specify it explicity.
-
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit e138e0ef9560c46ce93dbb22a728a57888e94d1c
- Author: Sujith Manoharan <[email protected]>
- Date: Mon Feb 3 13:31:37 2014 +0530
- ath9k: Fix TX power calculation
-
- The commit, "ath9k_hw: Fix incorrect Tx control power in AR9003 template"
- fixed the incorrect values in the eeprom templates, but if
- boards have already been calibrated with incorrect values,
- they would still be using the wrong TX power. Fix this by assigning
- a default value in such cases.
-
- Cc: Rajkumar Manoharan <[email protected]>
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit b9f268b5b01331c3c82179abca551429450e9417
- Author: Michal Kazior <[email protected]>
- Date: Wed Jan 29 14:22:27 2014 +0100
- cfg80211: consider existing DFS interfaces
-
- It was possible to break interface combinations in
- the following way:
-
- combo 1: iftype = AP, num_ifaces = 2, num_chans = 2,
- combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20
-
- With the above interface combinations it was
- possible to:
-
- step 1. start AP on DFS channel by matching combo 2
- step 2. start AP on non-DFS channel by matching combo 1
-
- This was possible beacuse (step 2) did not consider
- if other interfaces require radar detection.
-
- The patch changes how cfg80211 tracks channels -
- instead of channel itself now a complete chandef
- is stored.
-
- Signed-off-by: Michal Kazior <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28
- Author: Antonio Quartulli <[email protected]>
- Date: Wed Jan 29 17:53:43 2014 +0100
- cfg80211: fix channel configuration in IBSS join
-
- When receiving an IBSS_JOINED event select the BSS object
- based on the {bssid, channel} couple rather than the bssid
- only.
- With the current approach if another cell having the same
- BSSID (but using a different channel) exists then cfg80211
- picks up the wrong BSS object.
- The result is a mismatching channel configuration between
- cfg80211 and the driver, that can lead to any sort of
- problem.
-
- The issue can be triggered by having an IBSS sitting on
- given channel and then asking the driver to create a new
- cell using the same BSSID but with a different frequency.
- By passing the channel to cfg80211_get_bss() we can solve
- this ambiguity and retrieve/create the correct BSS object.
- All the users of cfg80211_ibss_joined() have been changed
- accordingly.
-
- Moreover WARN when cfg80211_ibss_joined() gets a NULL
- channel as argument and remove a bogus call of the same
- function in ath6kl (it does not make sense to call
- cfg80211_ibss_joined() with a zero BSSID on ibss-leave).
-
- Cc: Kalle Valo <[email protected]>
- Cc: Arend van Spriel <[email protected]>
- Cc: Bing Zhao <[email protected]>
- Cc: Jussi Kivilinna <[email protected]>
- Cc: [email protected]
- Acked-by: Kalle Valo <[email protected]>
- Signed-off-by: Antonio Quartulli <[email protected]>
- [minor code cleanup in ath6kl]
- Signed-off-by: Johannes Berg <[email protected]>
- commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85
- Author: Johannes Berg <[email protected]>
- Date: Fri Jan 24 14:41:44 2014 +0100
- mac80211: fix bufferable MMPDU RX handling
-
- Action, disassoc and deauth frames are bufferable, and as such don't
- have the PM bit in the frame control field reserved which means we
- need to react to the bit when receiving in such a frame.
-
- Fix this by introducing a new helper ieee80211_is_bufferable_mmpdu()
- and using it for the RX path that currently ignores the PM bit in
- any non-data frames for doze->wake transitions, but listens to it in
- all frames for wake->doze transitions, both of which are wrong.
-
- Also use the new helper in the TX path to clean up the code.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit fc0df6d2343636e3f48a069330d5b972e3d8659d
- Author: Janusz Dziedzic <[email protected]>
- Date: Fri Jan 24 14:29:21 2014 +0100
- cfg80211: set preset_chandef after channel switch
-
- Set preset_chandef in channel switch notification.
- In other case we will have old preset_chandef.
-
- Signed-off-by: Janusz Dziedzic <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit cdec895e2344987ff171cece96e25d7407a3ebf6
- Author: Simon Wunderlich <[email protected]>
- Date: Fri Jan 24 23:48:29 2014 +0100
- mac80211: send ibss probe responses with noack flag
-
- Responding to probe requests for scanning clients will often create
- excessive retries, as it happens quite often that the scanning client
- already left the channel. Therefore do it like hostapd and send probe
- responses for wildcard SSID only once by using the noack flag.
-
- Signed-off-by: Simon Wunderlich <[email protected]>
- [fix typo & 'wildcard SSID' in commit log]
- Signed-off-by: Johannes Berg <[email protected]>
- commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b
- Author: Luciano Coelho <[email protected]>
- Date: Tue Jan 28 17:09:08 2014 +0200
- mac80211: ibss: remove unnecessary call to release channel
-
- The ieee80211_vif_use_channel() function calls
- ieee80211_vif_release_channel(), so there's no need to call it
- explicitly in __ieee80211_sta_join_ibss().
-
- Signed-off-by: Luciano Coelho <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7
- Author: Michal Kazior <[email protected]>
- Date: Wed Jan 29 07:56:21 2014 +0100
- mac80211: add missing CSA locking
-
- The patch adds a missing sdata lock and adds a few
- lockdeps for easier maintenance.
-
- Signed-off-by: Michal Kazior <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit ad17ba7d14d225b109b73c177cd446afb8050598
- Author: Michal Kazior <[email protected]>
- Date: Wed Jan 29 07:56:20 2014 +0100
- mac80211: fix sdata->radar_required locking
-
- radar_required setting wasn't protected by
- local->mtx in some places. This should prevent
- from scanning/radar detection/roc colliding.
-
- Signed-off-by: Michal Kazior <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d
- Author: Michal Kazior <[email protected]>
- Date: Wed Jan 29 07:56:19 2014 +0100
- mac80211: move csa_active setting in STA CSA
-
- The sdata->vif.csa_active could be left set after,
- e.g. channel context constraints check fail in STA
- mode leaving the interface in a strange state for
- a brief period of time until it is disconnected.
- This was harmless but ugly.
-
- Signed-off-by: Michal Kazior <[email protected]>
- Reviewed-by: Luciano Coelho <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9
- Author: Michal Kazior <[email protected]>
- Date: Wed Jan 29 07:56:18 2014 +0100
- mac80211: fix possible memory leak on AP CSA failure
-
- If CSA for AP interface failed and the interface
- was not stopped afterwards another CSA request
- would leak sdata->u.ap.next_beacon.
-
- Signed-off-by: Michal Kazior <[email protected]>
- Reviewed-by: Luciano Coelho <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit 3a77ba08940682bf3d52cf14f980337324af9d4a
- Author: Johannes Berg <[email protected]>
- Date: Sat Feb 1 00:33:29 2014 +0100
- mac80211: fix fragmentation code, particularly for encryption
-
- The "new" fragmentation code (since my rewrite almost 5 years ago)
- erroneously sets skb->len rather than using skb_trim() to adjust
- the length of the first fragment after copying out all the others.
- This leaves the skb tail pointer pointing to after where the data
- originally ended, and thus causes the encryption MIC to be written
- at that point, rather than where it belongs: immediately after the
- data.
-
- The impact of this is that if software encryption is done, then
- a) encryption doesn't work for the first fragment, the connection
- becomes unusable as the first fragment will never be properly
- verified at the receiver, the MIC is practically guaranteed to
- be wrong
- b) we leak up to 8 bytes of plaintext (!) of the packet out into
- the air
-
- This is only mitigated by the fact that many devices are capable
- of doing encryption in hardware, in which case this can't happen
- as the tail pointer is irrelevant in that case. Additionally,
- fragmentation is not used very frequently and would normally have
- to be configured manually.
-
- Fix this by using skb_trim() properly.
-
- Cc: [email protected]
- Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
- Reported-by: Jouni Malinen <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit de5f242e0c10e841017e37eb8c38974a642dbca8
- Author: Sujith Manoharan <[email protected]>
- Date: Tue Jan 28 06:21:59 2014 +0530
- ath9k: Fix build error on ARM
-
- Use mdelay instead of udelay to fix this error:
-
- ERROR: "__bad_udelay" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!
- make[1]: *** [__modpost] Error 1
- make: *** [modules] Error 2
-
- Reported-by: Josh Boyer <[email protected]>
- Signed-off-by: Sujith Manoharan <[email protected]>
- commit 8e3ea7a51dfc61810fcefd947f6edcf61125252a
- Author: Geert Uytterhoeven <[email protected]>
- Date: Sun Jan 26 11:53:21 2014 +0100
- ath9k: Fix uninitialized variable in ath9k_has_tx_pending()
-
- drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_has_tx_pending’:
- drivers/net/wireless/ath/ath9k/main.c:1869: warning: ‘npend’ may be used uninitialized in this function
-
- Introduced by commit 10e2318103f5941aa70c318afe34bc41f1b98529 ("ath9k:
- optimize ath9k_flush").
-
- Signed-off-by: Geert Uytterhoeven <[email protected]>
- commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6
- Author: Emmanuel Grumbach <[email protected]>
- Date: Mon Jan 27 11:07:42 2014 +0200
- mac80211: release the channel in error path in start_ap
-
- When the driver cannot start the AP or when the assignement
- of the beacon goes wrong, we need to unassign the vif.
-
- Cc: [email protected]
- Signed-off-by: Emmanuel Grumbach <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit dfb6889a75c601aedb7450b7e606668e77da6679
- Author: Johannes Berg <[email protected]>
- Date: Wed Jan 22 11:14:19 2014 +0200
- cfg80211: send scan results from work queue
-
- Due to the previous commit, when a scan finishes, it is in theory
- possible to hit the following sequence:
- 1. interface starts being removed
- 2. scan is cancelled by driver and cfg80211 is notified
- 3. scan done work is scheduled
- 4. interface is removed completely, rdev->scan_req is freed,
- event sent to userspace but scan done work remains pending
- 5. new scan is requested on another virtual interface
- 6. scan done work runs, freeing the still-running scan
-
- To fix this situation, hang on to the scan done message and block
- new scans while that is the case, and only send the message from
- the work function, regardless of whether the scan_req is already
- freed from interface removal. This makes step 5 above impossible
- and changes step 6 to be
- 5. scan done work runs, sending the scan done message
-
- As this can't work for wext, so we send the message immediately,
- but this shouldn't be an issue since we still return -EBUSY.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit 45b7ab41fc08627d9a8428cb413d5d84662a9707
- Author: Johannes Berg <[email protected]>
- Date: Wed Jan 22 11:14:18 2014 +0200
- cfg80211: fix scan done race
-
- When an interface/wdev is removed, any ongoing scan should be
- cancelled by the driver. This will make it call cfg80211, which
- only queues a work struct. If interface/wdev removal is quick
- enough, this can leave the scan request pending and processed
- only after the interface is gone, causing a use-after-free.
-
- Fix this by making sure the scan request is not pending after
- the interface is destroyed. We can't flush or cancel the work
- item due to locking concerns, but when it'll run it shouldn't
- find anything to do. This leaves a potential issue, if a new
- scan gets requested before the work runs, it prematurely stops
- the running scan, potentially causing another crash. I'll fix
- that in the next patch.
-
- This was particularly observed with P2P_DEVICE wdevs, likely
- because freeing them is quicker than freeing netdevs.
-
- Reported-by: Andrei Otcheretianski <[email protected]>
- Fixes: 4a58e7c38443 ("cfg80211: don't "leak" uncompleted scans")
- Signed-off-by: Johannes Berg <[email protected]>
- commit ae04fa489ab31b5a10d3cc8399f52761175d4321
- Author: Emmanuel Grumbach <[email protected]>
- Date: Thu Jan 23 14:28:16 2014 +0200
- mac80211: avoid deadlock revealed by lockdep
-
- sdata->u.ap.request_smps_work can’t be flushed synchronously
- under wdev_lock(wdev) since ieee80211_request_smps_ap_work
- itself locks the same lock.
- While at it, reset the driver_smps_mode when the ap is
- stopped to its default: OFF.
-
- This solves:
-
- ======================================================
- [ INFO: possible circular locking dependency detected ]
- 3.12.0-ipeer+ #2 Tainted: G O
- -------------------------------------------------------
- rmmod/2867 is trying to acquire lock:
- ((&sdata->u.ap.request_smps_work)){+.+...}, at: [<c105b8d0>] flush_work+0x0/0x90
-
- but task is already holding lock:
- (&wdev->mtx){+.+.+.}, at: [<f9b32626>] cfg80211_stop_ap+0x26/0x230 [cfg80211]
-
- which lock already depends on the new lock.
-
- the existing dependency chain (in reverse order) is:
-
- -> #1 (&wdev->mtx){+.+.+.}:
- [<c10aefa9>] lock_acquire+0x79/0xe0
- [<c1607a1a>] mutex_lock_nested+0x4a/0x360
- [<fb06288b>] ieee80211_request_smps_ap_work+0x2b/0x50 [mac80211]
- [<c105cdd8>] process_one_work+0x198/0x450
- [<c105d469>] worker_thread+0xf9/0x320
- [<c10669ff>] kthread+0x9f/0xb0
- [<c1613397>] ret_from_kernel_thread+0x1b/0x28
-
- -> #0 ((&sdata->u.ap.request_smps_work)){+.+...}:
- [<c10ae9df>] __lock_acquire+0x183f/0x1910
- [<c10aefa9>] lock_acquire+0x79/0xe0
- [<c105b917>] flush_work+0x47/0x90
- [<c105d867>] __cancel_work_timer+0x67/0xe0
- [<c105d90f>] cancel_work_sync+0xf/0x20
- [<fb0765cc>] ieee80211_stop_ap+0x8c/0x340 [mac80211]
- [<f9b3268c>] cfg80211_stop_ap+0x8c/0x230 [cfg80211]
- [<f9b0d8f9>] cfg80211_leave+0x79/0x100 [cfg80211]
- [<f9b0da72>] cfg80211_netdev_notifier_call+0xf2/0x4f0 [cfg80211]
- [<c160f2c9>] notifier_call_chain+0x59/0x130
- [<c106c6de>] __raw_notifier_call_chain+0x1e/0x30
- [<c106c70f>] raw_notifier_call_chain+0x1f/0x30
- [<c14f8213>] call_netdevice_notifiers_info+0x33/0x70
- [<c14f8263>] call_netdevice_notifiers+0x13/0x20
- [<c14f82a4>] __dev_close_many+0x34/0xb0
- [<c14f83fe>] dev_close_many+0x6e/0xc0
- [<c14f9c77>] rollback_registered_many+0xa7/0x1f0
- [<c14f9dd4>] unregister_netdevice_many+0x14/0x60
- [<fb06f4d9>] ieee80211_remove_interfaces+0xe9/0x170 [mac80211]
- [<fb055116>] ieee80211_unregister_hw+0x56/0x110 [mac80211]
- [<fa3e9396>] iwl_op_mode_mvm_stop+0x26/0xe0 [iwlmvm]
- [<f9b9d8ca>] _iwl_op_mode_stop+0x3a/0x70 [iwlwifi]
- [<f9b9d96f>] iwl_opmode_deregister+0x6f/0x90 [iwlwifi]
- [<fa405179>] __exit_compat+0xd/0x19 [iwlmvm]
- [<c10b8bf9>] SyS_delete_module+0x179/0x2b0
- [<c1613421>] sysenter_do_call+0x12/0x32
-
- Fixes: 687da132234f ("mac80211: implement SMPS for AP")
- Cc: <[email protected]> [3.13]
- Reported-by: Ilan Peer <[email protected]>
- Signed-off-by: Emmanuel Grumbach <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit 178b205e96217164fd7c30113464250d0b6f5eca
- Author: Johannes Berg <[email protected]>
- Date: Thu Jan 23 16:32:29 2014 +0100
- cfg80211: re-enable 5/10 MHz support
-
- Unfortunately I forgot this during the merge window, but the
- patch seems small enough to go in as a fix. The userspace API
- bug that was the reason for disabling it has long been fixed.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61
- Author: Pontus Fuchs <[email protected]>
- Date: Thu Jan 16 15:00:40 2014 +0100
- nl80211: Reset split_start when netlink skb is exhausted
-
- When the netlink skb is exhausted split_start is left set. In the
- subsequent retry, with a larger buffer, the dump is continued from the
- failing point instead of from the beginning.
-
- This was causing my rt28xx based USB dongle to now show up when
- running "iw list" with an old iw version without split dump support.
-
- Cc: [email protected]
- Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
- Signed-off-by: Pontus Fuchs <[email protected]>
- [avoid the entire workaround when state->split is set]
- Signed-off-by: Johannes Berg <[email protected]>
- commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4
- Author: Eliad Peller <[email protected]>
- Date: Sun Jan 12 11:06:37 2014 +0200
- mac80211: move roc cookie assignment earlier
-
- ieee80211_start_roc_work() might add a new roc
- to existing roc, and tell cfg80211 it has already
- started.
-
- However, this might happen before the roc cookie
- was set, resulting in REMAIN_ON_CHANNEL (started)
- event with null cookie. Consequently, it can make
- wpa_supplicant go out of sync.
-
- Fix it by setting the roc cookie earlier.
-
- Cc: [email protected]
- Signed-off-by: Eliad Peller <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c
- Author: Johannes Berg <[email protected]>
- Date: Fri Jan 24 14:06:29 2014 +0100
- nl80211: send event when AP operation is stopped
-
- There are a few cases, e.g. suspend, where an AP interface is
- stopped by the kernel rather than by userspace request, most
- commonly when suspending. To let userspace know about this,
- send the NL80211_CMD_STOP_AP command as an event every time
- an AP interface is stopped. This also happens when userspace
- did in fact request the AP stop, but that's not a problem.
-
- For full-MAC drivers this may need to be extended to also
- cover cases where the device stopped the AP operation for
- some reason, this a bit more complicated because then all
- cfg80211 state also needs to be reset; such API is not part
- of this patch.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit d5d567eda7704f190379ca852a8f9a4112e3eee3
- Author: Johannes Berg <[email protected]>
- Date: Thu Jan 23 16:20:29 2014 +0100
- mac80211: add length check in ieee80211_is_robust_mgmt_frame()
-
- A few places weren't checking that the frame passed to the
- function actually has enough data even though the function
- clearly documents it must have a payload byte. Make this
- safer by changing the function to take an skb and checking
- the length inside. The old version is preserved for now as
- the rtl* drivers use it and don't have a correct skb.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit f8f6d212a047fc65c7d3442dfc038f65517236fc
- Author: Johannes Berg <[email protected]>
- Date: Fri Jan 24 10:53:53 2014 +0100
- nl80211: fix scheduled scan RSSI matchset attribute confusion
-
- The scheduled scan matchsets were intended to be a list of filters,
- with the found BSS having to pass at least one of them to be passed
- to the host. When the RSSI attribute was added, however, this was
- broken and currently wpa_supplicant adds that attribute in its own
- matchset; however, it doesn't intend that to mean that anything
- that passes the RSSI filter should be passed to the host, instead
- it wants it to mean that everything needs to also have higher RSSI.
-
- This is semantically problematic because we have a list of filters
- like [ SSID1, SSID2, SSID3, RSSI ] with no real indication which
- one should be OR'ed and which one AND'ed.
-
- To fix this, move the RSSI filter attribute into each matchset. As
- we need to stay backward compatible, treat a matchset with only the
- RSSI attribute as a "default RSSI filter" for all other matchsets,
- but only if there are other matchsets (an RSSI-only matchset by
- itself is still desirable.)
-
- To make driver implementation easier, keep a global min_rssi_thold
- for the entire request as well. The only affected driver is ath6kl.
-
- I found this when I looked into the code after Raja Mani submitted
- a patch fixing the n_match_sets calculation to disregard the RSSI,
- but that patch didn't address the semantic issue.
-
- Reported-by: Raja Mani <[email protected]>
- Acked-by: Luciano Coelho <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- commit de553e8545e65a6dc4e45f43df7e1443d4291922
- Author: Johannes Berg <[email protected]>
- Date: Fri Jan 24 10:17:47 2014 +0100
- nl80211: check nla_parse() return values
-
- If there's a policy, then nla_parse() return values must be
- checked, otherwise the policy is useless and there's nothing
- that ensures the attributes are actually what we expect them
- to be.
-
- Signed-off-by: Johannes Berg <[email protected]>
- commit 652204a0733e9e1c54661d6f9d36e2e1e3b22bb1
- Author: Karl Beldan <[email protected]>
- Date: Thu Jan 23 20:06:34 2014 +0100
- mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec
-
- ATM, {ADD,DEL}BA and BAR frames are sent on the AC matching the TID of
- the BA parameters. In the discussion [1] about this patch, Johannes
- recalled that it fixed some races with the DELBA and indeed this
- behavior was introduced in [2].
- While [2] is right for the BARs, the part queueing the {ADD,DEL}BAs on
- their BA params TID AC violates the spec and is more a workaround for
- some drivers. Helmut expressed some concerns wrt such drivers, in
- particular DELBAs in rt2x00.
-
- ATM, DELBAs are sent after a driver has called (hence "purposely")
- ieee80211_start_tx_ba_cb_irqsafe and Johannes and Emmanuel gave some
- details wrt intentions behind the split of the IEEE80211_AMPDU_TX_STOP_*
- given to the driver ampdu_action supposed to call this function, which
- could prove handy to people trying to do the right thing in faulty
- drivers (if their fw/hw don't get in their way).
-
- [1] http://mid.gmane.org/[email protected]
- [2] Commit: cf6bb79ad828 ("mac80211: Use appropriate TID for sending BAR, ADDBA and DELBA frames")
-
- Signed-off-by: Karl Beldan <[email protected]>
- Cc: Helmut Schaa <[email protected]>
- Cc: Emmanuel Grumbach <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
- +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
- @@ -790,7 +790,7 @@ void ath6kl_cfg80211_connect_event(struc
- if (nw_type & ADHOC_NETWORK) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
- nw_type & ADHOC_CREATOR ? "creator" : "joiner");
- - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- + cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
- cfg80211_put_bss(ar->wiphy, bss);
- return;
- }
- @@ -861,13 +861,9 @@ void ath6kl_cfg80211_disconnect_event(st
- }
-
- if (vif->nw_type & ADHOC_NETWORK) {
- - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
- + if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in ibss mode\n", __func__);
- - return;
- - }
- - memset(bssid, 0, ETH_ALEN);
- - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- return;
- }
-
- @@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s
- struct ath6kl_vif *vif = netdev_priv(dev);
- u16 interval;
- int ret, rssi_thold;
- + int n_match_sets = request->n_match_sets;
- +
- + /*
- + * If there's a matchset w/o an SSID, then assume it's just for
- + * the RSSI (nothing else is currently supported) and ignore it.
- + * The device only supports a global RSSI filter that we set below.
- + */
- + if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
- + n_match_sets = 0;
-
- if (ar->state != ATH6KL_STATE_ON)
- return -EIO;
- @@ -3268,11 +3273,11 @@ static int ath6kl_cfg80211_sscan_start(s
- ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
- request->n_ssids,
- request->match_sets,
- - request->n_match_sets);
- + n_match_sets);
- if (ret < 0)
- return ret;
-
- - if (!request->n_match_sets) {
- + if (!n_match_sets) {
- ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- ALL_BSS_FILTER, 0);
- if (ret < 0)
- @@ -3286,12 +3291,12 @@ static int ath6kl_cfg80211_sscan_start(s
-
- if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
- ar->fw_capabilities)) {
- - if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
- + if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
- rssi_thold = 0;
- - else if (request->rssi_thold < -127)
- + else if (request->min_rssi_thold < -127)
- rssi_thold = -127;
- else
- - rssi_thold = request->rssi_thold;
- + rssi_thold = request->min_rssi_thold;
-
- ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
- rssi_thold);
- --- a/drivers/net/wireless/ath/ath9k/hw.c
- +++ b/drivers/net/wireless/ath/ath9k/hw.c
- @@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct at
- if (AR_SREV_9300_20_OR_LATER(ah))
- udelay(50);
- else if (AR_SREV_9100(ah))
- - udelay(10000);
- + mdelay(10);
- else
- udelay(100);
-
- @@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav);
- bool ath9k_hw_check_alive(struct ath_hw *ah)
- {
- int count = 50;
- - u32 reg;
- + u32 reg, last_val;
-
- if (AR_SREV_9300(ah))
- return !ath9k_hw_detect_mac_hang(ah);
- @@ -1542,9 +1542,13 @@ bool ath9k_hw_check_alive(struct ath_hw
- if (AR_SREV_9285_12_OR_LATER(ah))
- return true;
-
- + last_val = REG_READ(ah, AR_OBS_BUS_1);
- do {
- reg = REG_READ(ah, AR_OBS_BUS_1);
- + if (reg != last_val)
- + return true;
-
- + last_val = reg;
- if ((reg & 0x7E7FFFEF) == 0x00702400)
- continue;
-
- @@ -1556,6 +1560,8 @@ bool ath9k_hw_check_alive(struct ath_hw
- default:
- return true;
- }
- +
- + udelay(1);
- } while (count-- > 0);
-
- return false;
- @@ -2051,9 +2057,8 @@ static bool ath9k_hw_set_power_awake(str
-
- REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
- AR_RTC_FORCE_WAKE_EN);
- -
- if (AR_SREV_9100(ah))
- - udelay(10000);
- + mdelay(10);
- else
- udelay(50);
-
- --- a/drivers/net/wireless/ath/ath9k/main.c
- +++ b/drivers/net/wireless/ath/ath9k/main.c
- @@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data)
- * interrupts are enabled in the reset routine.
- */
- atomic_inc(&ah->intr_ref_cnt);
- - ath_dbg(common, ANY, "FATAL: Skipping interrupts\n");
- + ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
- goto out;
- }
-
- @@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
- * interrupts are enabled in the reset routine.
- */
- atomic_inc(&ah->intr_ref_cnt);
- - ath_dbg(common, ANY,
- + ath_dbg(common, RESET,
- "BB_WATCHDOG: Skipping interrupts\n");
- goto out;
- }
- @@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data)
- type = RESET_TYPE_TX_GTT;
- ath9k_queue_reset(sc, type);
- atomic_inc(&ah->intr_ref_cnt);
- - ath_dbg(common, ANY,
- + ath_dbg(common, RESET,
- "GTT: Skipping interrupts\n");
- goto out;
- }
- @@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str
-
- static bool ath9k_has_tx_pending(struct ath_softc *sc)
- {
- - int i, npend;
- + int i, npend = 0;
-
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (!ATH_TXQ_SETUP(sc, i))
- --- a/drivers/net/wireless/iwlwifi/mvm/scan.c
- +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
- @@ -595,6 +595,9 @@ static void iwl_scan_offload_build_ssid(
- * config match list.
- */
- for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) {
- + /* skip empty SSID matchsets */
- + if (!req->match_sets[i].ssid.ssid_len)
- + continue;
- scan->direct_scan[i].id = WLAN_EID_SSID;
- scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
- memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
- --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
- +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
- @@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80
- /* During testing, hdr was NULL */
- return false;
- }
- - if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
- + if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
- --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
- +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
- @@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80
- /* In testing, hdr was NULL here */
- return false;
- }
- - if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
- + if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
- --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
- +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
- @@ -310,7 +310,7 @@ bool rtl92se_rx_query_desc(struct ieee80
- /* during testing, hdr was NULL here */
- return false;
- }
- - if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
- + if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
- --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
- +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
- @@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee
- /* during testing, hdr could be NULL here */
- return false;
- }
- - if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
- + if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
- --- a/include/linux/ieee80211.h
- +++ b/include/linux/ieee80211.h
- @@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf
- }
-
- /**
- + * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
- + * @fc: frame control field in little-endian byteorder
- + */
- +static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
- +{
- + /* IEEE 802.11-2012, definition of "bufferable management frame";
- + * note that this ignores the IBSS special case. */
- + return ieee80211_is_mgmt(fc) &&
- + (ieee80211_is_action(fc) ||
- + ieee80211_is_disassoc(fc) ||
- + ieee80211_is_deauth(fc));
- +}
- +
- +/**
- * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
- * @seq_ctrl: frame sequence control bytes in little-endian byteorder
- */
- @@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc
- }
-
- /**
- - * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
- + * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
- * @hdr: the frame (buffer must include at least the first octet of payload)
- */
- -static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
- +static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
- {
- if (ieee80211_is_disassoc(hdr->frame_control) ||
- ieee80211_is_deauth(hdr->frame_control))
- @@ -2224,6 +2238,17 @@ static inline bool ieee80211_is_robust_m
- }
-
- /**
- + * ieee80211_is_robust_mgmt_frame - check if skb contains a robust mgmt frame
- + * @skb: the skb containing the frame, length will be checked
- + */
- +static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
- +{
- + if (skb->len < 25)
- + return false;
- + return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
- +}
- +
- +/**
- * ieee80211_is_public_action - check if frame is a public action frame
- * @hdr: the frame
- * @len: length of the frame
- --- a/include/net/cfg80211.h
- +++ b/include/net/cfg80211.h
- @@ -1395,9 +1395,11 @@ struct cfg80211_scan_request {
- * struct cfg80211_match_set - sets of attributes to match
- *
- * @ssid: SSID to be matched
- + * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
- */
- struct cfg80211_match_set {
- struct cfg80211_ssid ssid;
- + s32 rssi_thold;
- };
-
- /**
- @@ -1420,7 +1422,8 @@ struct cfg80211_match_set {
- * @dev: the interface
- * @scan_start: start time of the scheduled scan
- * @channels: channels to scan
- - * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
- + * @min_rssi_thold: for drivers only supporting a single threshold, this
- + * contains the minimum over all matchsets
- */
- struct cfg80211_sched_scan_request {
- struct cfg80211_ssid *ssids;
- @@ -1433,7 +1436,7 @@ struct cfg80211_sched_scan_request {
- u32 flags;
- struct cfg80211_match_set *match_sets;
- int n_match_sets;
- - s32 rssi_thold;
- + s32 min_rssi_thold;
-
- /* internal */
- struct wiphy *wiphy;
- @@ -3130,8 +3133,8 @@ struct cfg80211_cached_keys;
- * @identifier: (private) Identifier used in nl80211 to identify this
- * wireless device if it has no netdev
- * @current_bss: (private) Used by the internal configuration code
- - * @channel: (private) Used by the internal configuration code to track
- - * the user-set AP, monitor and WDS channel
- + * @chandef: (private) Used by the internal configuration code to track
- + * the user-set channel definition.
- * @preset_chandef: (private) Used by the internal configuration code to
- * track the channel to be used for AP later
- * @bssid: (private) Used by the internal configuration code
- @@ -3195,9 +3198,7 @@ struct wireless_dev {
-
- struct cfg80211_internal_bss *current_bss; /* associated / joined */
- struct cfg80211_chan_def preset_chandef;
- -
- - /* for AP and mesh channel tracking */
- - struct ieee80211_channel *channel;
- + struct cfg80211_chan_def chandef;
-
- bool ibss_fixed;
- bool ibss_dfs_possible;
- @@ -3879,6 +3880,7 @@ void cfg80211_michael_mic_failure(struct
- *
- * @dev: network device
- * @bssid: the BSSID of the IBSS joined
- + * @channel: the channel of the IBSS joined
- * @gfp: allocation flags
- *
- * This function notifies cfg80211 that the device joined an IBSS or
- @@ -3888,7 +3890,8 @@ void cfg80211_michael_mic_failure(struct
- * with the locally generated beacon -- this guarantees that there is
- * always a scan result for this IBSS. cfg80211 will handle the rest.
- */
- -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
- +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
- + struct ieee80211_channel *channel, gfp_t gfp);
-
- /**
- * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
- --- a/include/uapi/linux/nl80211.h
- +++ b/include/uapi/linux/nl80211.h
- @@ -2442,9 +2442,15 @@ enum nl80211_reg_rule_attr {
- * enum nl80211_sched_scan_match_attr - scheduled scan match attributes
- * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
- * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
- - * only report BSS with matching SSID.
- + * only report BSS with matching SSID.
- * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
- - * BSS in scan results. Filtering is turned off if not specified.
- + * BSS in scan results. Filtering is turned off if not specified. Note that
- + * if this attribute is in a match set of its own, then it is treated as
- + * the default value for all matchsets with an SSID, rather than being a
- + * matchset of its own without an RSSI filter. This is due to problems with
- + * how this API was implemented in the past. Also, due to the same problem,
- + * the only way to create a matchset with only an RSSI filter (with this
- + * attribute) is if there's only a single matchset with the RSSI attribute.
- * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
- * attribute number currently defined
- * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
- --- a/net/mac80211/agg-tx.c
- +++ b/net/mac80211/agg-tx.c
- @@ -107,7 +107,7 @@ static void ieee80211_send_addba_request
- mgmt->u.action.u.addba_req.start_seq_num =
- cpu_to_le16(start_seq_num << 4);
-
- - ieee80211_tx_skb_tid(sdata, skb, tid);
- + ieee80211_tx_skb(sdata, skb);
- }
-
- void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
- @@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wip
- /* TODO: make hostapd tell us what it wants */
- sdata->smps_mode = IEEE80211_SMPS_OFF;
- sdata->needed_rx_chains = sdata->local->rx_chains;
- - sdata->radar_required = params->radar_required;
-
- mutex_lock(&local->mtx);
- + sdata->radar_required = params->radar_required;
- err = ieee80211_vif_use_channel(sdata, ¶ms->chandef,
- IEEE80211_CHANCTX_SHARED);
- mutex_unlock(&local->mtx);
- @@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip
- IEEE80211_P2P_OPPPS_ENABLE_BIT;
-
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon);
- - if (err < 0)
- + if (err < 0) {
- + ieee80211_vif_release_channel(sdata);
- return err;
- + }
- changed |= err;
-
- err = drv_start_ap(sdata->local, sdata);
- @@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wip
- if (old)
- kfree_rcu(old, rcu_head);
- RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
- + ieee80211_vif_release_channel(sdata);
- return err;
- }
-
- @@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc
- int err;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- + sdata_assert_lock(sdata);
-
- /* don't allow changing the beacon while CSA is in place - offset
- * of channel switch counter may change
- @@ -1080,6 +1084,8 @@ static int ieee80211_stop_ap(struct wiph
- struct probe_resp *old_probe_resp;
- struct cfg80211_chan_def chandef;
-
- + sdata_assert_lock(sdata);
- +
- old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
- if (!old_beacon)
- return -ENOENT;
- @@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph
- kfree(sdata->u.ap.next_beacon);
- sdata->u.ap.next_beacon = NULL;
-
- - cancel_work_sync(&sdata->u.ap.request_smps_work);
- -
- /* turn off carrier for this interface and dependent VLANs */
- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
- netif_carrier_off(vlan->dev);
- @@ -1103,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiph
- kfree_rcu(old_beacon, rcu_head);
- if (old_probe_resp)
- kfree_rcu(old_probe_resp, rcu_head);
- + sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
-
- __sta_info_flush(sdata, true);
- ieee80211_free_keys(sdata, true);
- @@ -2638,6 +2643,24 @@ static int ieee80211_start_roc_work(stru
- INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
- INIT_LIST_HEAD(&roc->dependents);
-
- + /*
- + * cookie is either the roc cookie (for normal roc)
- + * or the SKB (for mgmt TX)
- + */
- + if (!txskb) {
- + /* local->mtx protects this */
- + local->roc_cookie_counter++;
- + roc->cookie = local->roc_cookie_counter;
- + /* wow, you wrapped 64 bits ... more likely a bug */
- + if (WARN_ON(roc->cookie == 0)) {
- + roc->cookie = 1;
- + local->roc_cookie_counter++;
- + }
- + *cookie = roc->cookie;
- + } else {
- + *cookie = (unsigned long)txskb;
- + }
- +
- /* if there's one pending or we're scanning, queue this one */
- if (!list_empty(&local->roc_list) ||
- local->scanning || local->radar_detect_enabled)
- @@ -2772,24 +2795,6 @@ static int ieee80211_start_roc_work(stru
- if (!queued)
- list_add_tail(&roc->list, &local->roc_list);
-
- - /*
- - * cookie is either the roc cookie (for normal roc)
- - * or the SKB (for mgmt TX)
- - */
- - if (!txskb) {
- - /* local->mtx protects this */
- - local->roc_cookie_counter++;
- - roc->cookie = local->roc_cookie_counter;
- - /* wow, you wrapped 64 bits ... more likely a bug */
- - if (WARN_ON(roc->cookie == 0)) {
- - roc->cookie = 1;
- - local->roc_cookie_counter++;
- - }
- - *cookie = roc->cookie;
- - } else {
- - *cookie = (unsigned long)txskb;
- - }
- -
- return 0;
- }
-
- @@ -3004,8 +3009,10 @@ void ieee80211_csa_finalize_work(struct
- if (!ieee80211_sdata_running(sdata))
- goto unlock;
-
- - sdata->radar_required = sdata->csa_radar_required;
- + sdata_assert_lock(sdata);
- +
- mutex_lock(&local->mtx);
- + sdata->radar_required = sdata->csa_radar_required;
- err = ieee80211_vif_change_channel(sdata, &changed);
- mutex_unlock(&local->mtx);
- if (WARN_ON(err < 0))
- @@ -3022,13 +3029,13 @@ void ieee80211_csa_finalize_work(struct
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
- + kfree(sdata->u.ap.next_beacon);
- + sdata->u.ap.next_beacon = NULL;
- +
- if (err < 0)
- goto unlock;
-
- changed |= err;
- - kfree(sdata->u.ap.next_beacon);
- - sdata->u.ap.next_beacon = NULL;
- -
- ieee80211_bss_info_change_notify(sdata, err);
- break;
- case NL80211_IFTYPE_ADHOC:
- @@ -3066,7 +3073,7 @@ int ieee80211_channel_switch(struct wiph
- struct ieee80211_if_mesh __maybe_unused *ifmsh;
- int err, num_chanctx;
-
- - lockdep_assert_held(&sdata->wdev.mtx);
- + sdata_assert_lock(sdata);
-
- if (!list_empty(&local->roc_list) || local->scanning)
- return -EBUSY;
- --- a/net/mac80211/ht.c
- +++ b/net/mac80211/ht.c
- @@ -375,7 +375,7 @@ void ieee80211_send_delba(struct ieee802
- mgmt->u.action.u.delba.params = cpu_to_le16(params);
- mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
-
- - ieee80211_tx_skb_tid(sdata, skb, tid);
- + ieee80211_tx_skb(sdata, skb);
- }
-
- void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
- @@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(stru
- u.ap.request_smps_work);
-
- sdata_lock(sdata);
- - __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode);
- + if (sdata_dereference(sdata->u.ap.beacon, sdata))
- + __ieee80211_request_smps_ap(sdata,
- + sdata->u.ap.driver_smps_mode);
- sdata_unlock(sdata);
- }
-
- --- a/net/mac80211/iface.c
- +++ b/net/mac80211/iface.c
- @@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee
-
- ieee80211_roc_purge(local, sdata);
-
- - if (sdata->vif.type == NL80211_IFTYPE_STATION)
- + switch (sdata->vif.type) {
- + case NL80211_IFTYPE_STATION:
- ieee80211_mgd_stop(sdata);
- -
- - if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
- + break;
- + case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_stop(sdata);
- -
- + break;
- + case NL80211_IFTYPE_AP:
- + cancel_work_sync(&sdata->u.ap.request_smps_work);
- + break;
- + default:
- + break;
- + }
-
- /*
- * Remove all stations associated with this interface.
- @@ -827,7 +834,9 @@ static void ieee80211_do_stop(struct iee
- cancel_work_sync(&local->dynamic_ps_enable_work);
-
- cancel_work_sync(&sdata->recalc_smps);
- + sdata_lock(sdata);
- sdata->vif.csa_active = false;
- + sdata_unlock(sdata);
- cancel_work_sync(&sdata->csa_finalize_work);
-
- cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
- --- a/net/mac80211/rx.c
- +++ b/net/mac80211/rx.c
- @@ -599,10 +599,10 @@ static int ieee80211_is_unicast_robust_m
- {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
- - if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
- + if (is_multicast_ether_addr(hdr->addr1))
- return 0;
-
- - return ieee80211_is_robust_mgmt_frame(hdr);
- + return ieee80211_is_robust_mgmt_frame(skb);
- }
-
-
- @@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust
- {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
- - if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
- + if (!is_multicast_ether_addr(hdr->addr1))
- return 0;
-
- - return ieee80211_is_robust_mgmt_frame(hdr);
- + return ieee80211_is_robust_mgmt_frame(skb);
- }
-
-
- @@ -626,7 +626,7 @@ static int ieee80211_get_mmie_keyidx(str
- if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
- return -1;
-
- - if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
- + if (!ieee80211_is_robust_mgmt_frame(skb))
- return -1; /* not a robust management frame */
-
- mmie = (struct ieee80211_mmie *)
- @@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *
- sta->sta.addr, sta->sta.aid);
-
- if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
- + /*
- + * Clear the flag only if the other one is still set
- + * so that the TX path won't start TX'ing new frames
- + * directly ... In the case that the driver flag isn't
- + * set ieee80211_sta_ps_deliver_wakeup() will clear it.
- + */
- + clear_sta_flag(sta, WLAN_STA_PS_STA);
- ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n",
- sta->sta.addr, sta->sta.aid);
- return;
- @@ -1311,18 +1318,15 @@ ieee80211_rx_h_sta_process(struct ieee80
- !ieee80211_has_morefrags(hdr->frame_control) &&
- !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
- (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
- - rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
- + rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
- + /* PM bit is only checked in frames where it isn't reserved,
- + * in AP mode it's reserved in non-bufferable management frames
- + * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
- + */
- + (!ieee80211_is_mgmt(hdr->frame_control) ||
- + ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
- if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
- - /*
- - * Ignore doze->wake transitions that are
- - * indicated by non-data frames, the standard
- - * is unclear here, but for example going to
- - * PS mode and then scanning would cause a
- - * doze->wake transition for the probe request,
- - * and that is clearly undesirable.
- - */
- - if (ieee80211_is_data(hdr->frame_control) &&
- - !ieee80211_has_pm(hdr->frame_control))
- + if (!ieee80211_has_pm(hdr->frame_control))
- sta_ps_end(sta);
- } else {
- if (ieee80211_has_pm(hdr->frame_control))
- @@ -1845,8 +1849,7 @@ static int ieee80211_drop_unencrypted_mg
- * having configured keys.
- */
- if (unlikely(ieee80211_is_action(fc) && !rx->key &&
- - ieee80211_is_robust_mgmt_frame(
- - (struct ieee80211_hdr *) rx->skb->data)))
- + ieee80211_is_robust_mgmt_frame(rx->skb)))
- return -EACCES;
- }
-
- --- a/net/mac80211/tx.c
- +++ b/net/mac80211/tx.c
- @@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc,
- if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
- return 0;
-
- - if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
- - skb->data))
- + if (!ieee80211_is_robust_mgmt_frame(skb))
- return 0;
-
- return 1;
- @@ -478,6 +477,20 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- sta->sta.addr, sta->sta.aid, ac);
- if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
- purge_old_ps_buffers(tx->local);
- +
- + /* sync with ieee80211_sta_ps_deliver_wakeup */
- + spin_lock(&sta->ps_lock);
- + /*
- + * STA woke up the meantime and all the frames on ps_tx_buf have
- + * been queued to pending queue. No reordering can happen, go
- + * ahead and Tx the packet.
- + */
- + if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
- + !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
- + spin_unlock(&sta->ps_lock);
- + return TX_CONTINUE;
- + }
- +
- if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
- struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
- ps_dbg(tx->sdata,
- @@ -492,6 +505,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
- info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
- skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
- + spin_unlock(&sta->ps_lock);
-
- if (!timer_pending(&local->sta_cleanup))
- mod_timer(&local->sta_cleanup,
- @@ -525,9 +539,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
-
- /* only deauth, disassoc and action are bufferable MMPDUs */
- if (ieee80211_is_mgmt(hdr->frame_control) &&
- - !ieee80211_is_deauth(hdr->frame_control) &&
- - !ieee80211_is_disassoc(hdr->frame_control) &&
- - !ieee80211_is_action(hdr->frame_control)) {
- + !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
- if (tx->flags & IEEE80211_TX_UNICAST)
- info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
- return TX_CONTINUE;
- @@ -567,7 +579,7 @@ ieee80211_tx_h_select_key(struct ieee802
- tx->key = key;
- else if (ieee80211_is_mgmt(hdr->frame_control) &&
- is_multicast_ether_addr(hdr->addr1) &&
- - ieee80211_is_robust_mgmt_frame(hdr) &&
- + ieee80211_is_robust_mgmt_frame(tx->skb) &&
- (key = rcu_dereference(tx->sdata->default_mgmt_key)))
- tx->key = key;
- else if (is_multicast_ether_addr(hdr->addr1) &&
- @@ -582,12 +594,12 @@ ieee80211_tx_h_select_key(struct ieee802
- tx->key = NULL;
- else if (tx->skb->protocol == tx->sdata->control_port_protocol)
- tx->key = NULL;
- - else if (ieee80211_is_robust_mgmt_frame(hdr) &&
- + else if (ieee80211_is_robust_mgmt_frame(tx->skb) &&
- !(ieee80211_is_action(hdr->frame_control) &&
- tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))
- tx->key = NULL;
- else if (ieee80211_is_mgmt(hdr->frame_control) &&
- - !ieee80211_is_robust_mgmt_frame(hdr))
- + !ieee80211_is_robust_mgmt_frame(tx->skb))
- tx->key = NULL;
- else {
- I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
- @@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee
- }
-
- /* adjust first fragment's length */
- - skb->len = hdrlen + per_fragm;
- + skb_trim(skb, hdrlen + per_fragm);
- return 0;
- }
-
- --- a/net/mac80211/wpa.c
- +++ b/net/mac80211/wpa.c
- @@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
- if (!ieee80211_is_data(hdr->frame_control) &&
- - !ieee80211_is_robust_mgmt_frame(hdr))
- + !ieee80211_is_robust_mgmt_frame(skb))
- return RX_CONTINUE;
-
- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
- --- a/net/wireless/ap.c
- +++ b/net/wireless/ap.c
- @@ -27,9 +27,10 @@ static int __cfg80211_stop_ap(struct cfg
- err = rdev_stop_ap(rdev, dev);
- if (!err) {
- wdev->beacon_interval = 0;
- - wdev->channel = NULL;
- + memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- wdev->ssid_len = 0;
- rdev_set_qos_map(rdev, dev, NULL);
- + nl80211_send_ap_stopped(wdev);
- }
-
- return err;
- --- a/net/wireless/core.c
- +++ b/net/wireless/core.c
- @@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg
-
- rdev->opencount--;
-
- - WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
- - !rdev->scan_req->notified);
- + if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
- + if (WARN_ON(!rdev->scan_req->notified))
- + rdev->scan_req->aborted = true;
- + ___cfg80211_scan_done(rdev, false);
- + }
- }
-
- static int cfg80211_rfkill_set_block(void *data, bool blocked)
- @@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy)
- int i;
- u16 ifmodes = wiphy->interface_modes;
-
- - /* support for 5/10 MHz is broken due to nl80211 API mess - disable */
- - wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
- -
- /*
- * There are major locking problems in nl80211/mac80211 for CSA,
- * disable for all drivers until this has been reworked.
- @@ -875,8 +875,11 @@ static int cfg80211_netdev_notifier_call
- break;
- case NETDEV_DOWN:
- cfg80211_update_iface_num(rdev, wdev->iftype, -1);
- - WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
- - !rdev->scan_req->notified);
- + if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
- + if (WARN_ON(!rdev->scan_req->notified))
- + rdev->scan_req->aborted = true;
- + ___cfg80211_scan_done(rdev, false);
- + }
-
- if (WARN_ON(rdev->sched_scan_req &&
- rdev->sched_scan_req->dev == wdev->netdev)) {
- --- a/net/wireless/core.h
- +++ b/net/wireless/core.h
- @@ -62,6 +62,7 @@ struct cfg80211_registered_device {
- struct rb_root bss_tree;
- u32 bss_generation;
- struct cfg80211_scan_request *scan_req; /* protected by RTNL */
- + struct sk_buff *scan_msg;
- struct cfg80211_sched_scan_request *sched_scan_req;
- unsigned long suspend_at;
- struct work_struct scan_done_wk;
- @@ -210,6 +211,7 @@ struct cfg80211_event {
- } dc;
- struct {
- u8 bssid[ETH_ALEN];
- + struct ieee80211_channel *channel;
- } ij;
- };
- };
- @@ -257,7 +259,8 @@ int __cfg80211_leave_ibss(struct cfg8021
- struct net_device *dev, bool nowext);
- int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
- struct net_device *dev, bool nowext);
- -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
- +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
- + struct ieee80211_channel *channel);
- int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
- struct wireless_dev *wdev);
-
- @@ -361,7 +364,8 @@ int cfg80211_validate_key_settings(struc
- struct key_params *params, int key_idx,
- bool pairwise, const u8 *mac_addr);
- void __cfg80211_scan_done(struct work_struct *wk);
- -void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
- +void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
- + bool send_message);
- void __cfg80211_sched_scan_results(struct work_struct *wk);
- int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
- bool driver_initiated);
- @@ -441,7 +445,8 @@ static inline unsigned int elapsed_jiffi
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- struct ieee80211_channel **chan,
- - enum cfg80211_chan_mode *chanmode);
- + enum cfg80211_chan_mode *chanmode,
- + u8 *radar_detect);
-
- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
- struct cfg80211_chan_def *chandef);
- --- a/net/wireless/nl80211.c
- +++ b/net/wireless/nl80211.c
- @@ -1723,9 +1723,10 @@ static int nl80211_dump_wiphy(struct sk_
- * We can then retry with the larger buffer.
- */
- if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
- - !skb->len &&
- + !skb->len && !state->split &&
- cb->min_dump_alloc < 4096) {
- cb->min_dump_alloc = 4096;
- + state->split_start = 0;
- rtnl_unlock();
- return 1;
- }
- @@ -2047,10 +2048,12 @@ static int nl80211_set_wiphy(struct sk_b
- nla_for_each_nested(nl_txq_params,
- info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
- rem_txq_params) {
- - nla_parse(tb, NL80211_TXQ_ATTR_MAX,
- - nla_data(nl_txq_params),
- - nla_len(nl_txq_params),
- - txq_params_policy);
- + result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
- + nla_data(nl_txq_params),
- + nla_len(nl_txq_params),
- + txq_params_policy);
- + if (result)
- + goto bad_res;
- result = parse_txq_params(tb, &txq_params);
- if (result)
- goto bad_res;
- @@ -3289,7 +3292,7 @@ static int nl80211_start_ap(struct sk_bu
- if (!err) {
- wdev->preset_chandef = params.chandef;
- wdev->beacon_interval = params.beacon_interval;
- - wdev->channel = params.chandef.chan;
- + wdev->chandef = params.chandef;
- wdev->ssid_len = params.ssid_len;
- memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
- }
- @@ -5210,9 +5213,11 @@ static int nl80211_set_reg(struct sk_buf
-
- nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
- rem_reg_rules) {
- - nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
- - nla_data(nl_reg_rule), nla_len(nl_reg_rule),
- - reg_rule_policy);
- + r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
- + nla_data(nl_reg_rule), nla_len(nl_reg_rule),
- + reg_rule_policy);
- + if (r)
- + goto bad_reg;
- r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
- if (r)
- goto bad_reg;
- @@ -5277,7 +5282,7 @@ static int nl80211_trigger_scan(struct s
- if (!rdev->ops->scan)
- return -EOPNOTSUPP;
-
- - if (rdev->scan_req) {
- + if (rdev->scan_req || rdev->scan_msg) {
- err = -EBUSY;
- goto unlock;
- }
- @@ -5475,6 +5480,7 @@ static int nl80211_start_sched_scan(stru
- enum ieee80211_band band;
- size_t ie_len;
- struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
- + s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
-
- if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
- !rdev->ops->sched_scan_start)
- @@ -5509,11 +5515,40 @@ static int nl80211_start_sched_scan(stru
- if (n_ssids > wiphy->max_sched_scan_ssids)
- return -EINVAL;
-
- - if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH])
- + /*
- + * First, count the number of 'real' matchsets. Due to an issue with
- + * the old implementation, matchsets containing only the RSSI attribute
- + * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
- + * RSSI for all matchsets, rather than their own matchset for reporting
- + * all APs with a strong RSSI. This is needed to be compatible with
- + * older userspace that treated a matchset with only the RSSI as the
- + * global RSSI for all other matchsets - if there are other matchsets.
- + */
- + if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
- nla_for_each_nested(attr,
- info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
- - tmp)
- - n_match_sets++;
- + tmp) {
- + struct nlattr *rssi;
- +
- + err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
- + nla_data(attr), nla_len(attr),
- + nl80211_match_policy);
- + if (err)
- + return err;
- + /* add other standalone attributes here */
- + if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
- + n_match_sets++;
- + continue;
- + }
- + rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
- + if (rssi)
- + default_match_rssi = nla_get_s32(rssi);
- + }
- + }
- +
- + /* However, if there's no other matchset, add the RSSI one */
- + if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
- + n_match_sets = 1;
-
- if (n_match_sets > wiphy->max_match_sets)
- return -EINVAL;
- @@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru
- tmp) {
- struct nlattr *ssid, *rssi;
-
- - nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
- - nla_data(attr), nla_len(attr),
- - nl80211_match_policy);
- + err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
- + nla_data(attr), nla_len(attr),
- + nl80211_match_policy);
- + if (err)
- + goto out_free;
- ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
- if (ssid) {
- + if (WARN_ON(i >= n_match_sets)) {
- + /* this indicates a programming error,
- + * the loop above should have verified
- + * things properly
- + */
- + err = -EINVAL;
- + goto out_free;
- + }
- +
- if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
- err = -EINVAL;
- goto out_free;
- @@ -5647,15 +5693,28 @@ static int nl80211_start_sched_scan(stru
- nla_data(ssid), nla_len(ssid));
- request->match_sets[i].ssid.ssid_len =
- nla_len(ssid);
- + /* special attribute - old implemenation w/a */
- + request->match_sets[i].rssi_thold =
- + default_match_rssi;
- + rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
- + if (rssi)
- + request->match_sets[i].rssi_thold =
- + nla_get_s32(rssi);
- }
- - rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
- - if (rssi)
- - request->rssi_thold = nla_get_u32(rssi);
- - else
- - request->rssi_thold =
- - NL80211_SCAN_RSSI_THOLD_OFF;
- i++;
- }
- +
- + /* there was no other matchset, so the RSSI one is alone */
- + if (i == 0)
- + request->match_sets[0].rssi_thold = default_match_rssi;
- +
- + request->min_rssi_thold = INT_MAX;
- + for (i = 0; i < n_match_sets; i++)
- + request->min_rssi_thold =
- + min(request->match_sets[i].rssi_thold,
- + request->min_rssi_thold);
- + } else {
- + request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
- }
-
- if (info->attrs[NL80211_ATTR_IE]) {
- @@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection
-
- err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
- if (!err) {
- - wdev->channel = chandef.chan;
- + wdev->chandef = chandef;
- wdev->cac_started = true;
- wdev->cac_start_time = jiffies;
- }
- @@ -7502,16 +7561,19 @@ static int nl80211_set_tx_bitrate_mask(s
- * directly to the enum ieee80211_band values used in cfg80211.
- */
- BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
- - nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
- - {
- + nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
- enum ieee80211_band band = nla_type(tx_rates);
- + int err;
- +
- if (band < 0 || band >= IEEE80211_NUM_BANDS)
- return -EINVAL;
- sband = rdev->wiphy.bands[band];
- if (sband == NULL)
- return -EINVAL;
- - nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
- - nla_len(tx_rates), nl80211_txattr_policy);
- + err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
- + nla_len(tx_rates), nl80211_txattr_policy);
- + if (err)
- + return err;
- if (tb[NL80211_TXRATE_LEGACY]) {
- mask.control[band].legacy = rateset_to_mask(
- sband,
- @@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8
- NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
-
- -void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
- - struct wireless_dev *wdev)
- +struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
- + struct wireless_dev *wdev, bool aborted)
- {
- struct sk_buff *msg;
-
- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
- - return;
- + return NULL;
-
- if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
- - NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
- + aborted ? NL80211_CMD_SCAN_ABORTED :
- + NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
- nlmsg_free(msg);
- - return;
- + return NULL;
- }
-
- - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
- - NL80211_MCGRP_SCAN, GFP_KERNEL);
- + return msg;
- }
-
- -void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
- - struct wireless_dev *wdev)
- +void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
- + struct sk_buff *msg)
- {
- - struct sk_buff *msg;
- -
- - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
- return;
-
- - if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
- - NL80211_CMD_SCAN_ABORTED) < 0) {
- - nlmsg_free(msg);
- - return;
- - }
- -
- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
- NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
- @@ -11158,7 +11211,8 @@ void cfg80211_ch_switch_notify(struct ne
- wdev->iftype != NL80211_IFTYPE_MESH_POINT))
- return;
-
- - wdev->channel = chandef->chan;
- + wdev->chandef = *chandef;
- + wdev->preset_chandef = *chandef;
- nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_notify);
- @@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct
- }
- EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
-
- +void nl80211_send_ap_stopped(struct wireless_dev *wdev)
- +{
- + struct wiphy *wiphy = wdev->wiphy;
- + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
- + struct sk_buff *msg;
- + void *hdr;
- +
- + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- + if (!msg)
- + return;
- +
- + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
- + if (!hdr)
- + goto out;
- +
- + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
- + nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
- + nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
- + goto out;
- +
- + genlmsg_end(msg, hdr);
- +
- + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
- + NL80211_MCGRP_MLME, GFP_KERNEL);
- + return;
- + out:
- + nlmsg_free(msg);
- +}
- +
- /* initialisation/exit functions */
-
- int nl80211_init(void)
- --- a/net/wireless/nl80211.h
- +++ b/net/wireless/nl80211.h
- @@ -8,10 +8,10 @@ void nl80211_exit(void);
- void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
- void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
- struct wireless_dev *wdev);
- -void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
- - struct wireless_dev *wdev);
- -void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
- - struct wireless_dev *wdev);
- +struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
- + struct wireless_dev *wdev, bool aborted);
- +void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
- + struct sk_buff *msg);
- void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u32 cmd);
- void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
- @@ -74,6 +74,8 @@ nl80211_radar_notify(struct cfg80211_reg
- enum nl80211_radar_event event,
- struct net_device *netdev, gfp_t gfp);
-
- +void nl80211_send_ap_stopped(struct wireless_dev *wdev);
- +
- void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
-
- #endif /* __NET_WIRELESS_NL80211_H */
- --- a/net/wireless/scan.c
- +++ b/net/wireless/scan.c
- @@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct
- dev->bss_generation++;
- }
-
- -void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
- +void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
- + bool send_message)
- {
- struct cfg80211_scan_request *request;
- struct wireless_dev *wdev;
- + struct sk_buff *msg;
- #ifdef CPTCFG_CFG80211_WEXT
- union iwreq_data wrqu;
- #endif
-
- ASSERT_RTNL();
-
- - request = rdev->scan_req;
- + if (rdev->scan_msg) {
- + nl80211_send_scan_result(rdev, rdev->scan_msg);
- + rdev->scan_msg = NULL;
- + return;
- + }
-
- + request = rdev->scan_req;
- if (!request)
- return;
-
- @@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802
- if (wdev->netdev)
- cfg80211_sme_scan_done(wdev->netdev);
-
- - if (request->aborted) {
- - nl80211_send_scan_aborted(rdev, wdev);
- - } else {
- - if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
- - /* flush entries from previous scans */
- - spin_lock_bh(&rdev->bss_lock);
- - __cfg80211_bss_expire(rdev, request->scan_start);
- - spin_unlock_bh(&rdev->bss_lock);
- - }
- - nl80211_send_scan_done(rdev, wdev);
- + if (!request->aborted &&
- + request->flags & NL80211_SCAN_FLAG_FLUSH) {
- + /* flush entries from previous scans */
- + spin_lock_bh(&rdev->bss_lock);
- + __cfg80211_bss_expire(rdev, request->scan_start);
- + spin_unlock_bh(&rdev->bss_lock);
- }
-
- + msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
- +
- #ifdef CPTCFG_CFG80211_WEXT
- if (wdev->netdev && !request->aborted) {
- memset(&wrqu, 0, sizeof(wrqu));
- @@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg802
-
- rdev->scan_req = NULL;
- kfree(request);
- +
- + if (!send_message)
- + rdev->scan_msg = msg;
- + else
- + nl80211_send_scan_result(rdev, msg);
- }
-
- void __cfg80211_scan_done(struct work_struct *wk)
- @@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st
- scan_done_wk);
-
- rtnl_lock();
- - ___cfg80211_scan_done(rdev);
- + ___cfg80211_scan_done(rdev, true);
- rtnl_unlock();
- }
-
- @@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev
- if (IS_ERR(rdev))
- return PTR_ERR(rdev);
-
- - if (rdev->scan_req) {
- + if (rdev->scan_req || rdev->scan_msg) {
- err = -EBUSY;
- goto out;
- }
- @@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev
- if (IS_ERR(rdev))
- return PTR_ERR(rdev);
-
- - if (rdev->scan_req)
- + if (rdev->scan_req || rdev->scan_msg)
- return -EAGAIN;
-
- res = ieee80211_scan_results(rdev, info, extra, data->length);
- --- a/net/wireless/sme.c
- +++ b/net/wireless/sme.c
- @@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wir
- ASSERT_RDEV_LOCK(rdev);
- ASSERT_WDEV_LOCK(wdev);
-
- - if (rdev->scan_req)
- + if (rdev->scan_req || rdev->scan_msg)
- return -EBUSY;
-
- if (wdev->conn->params.channel)
- --- a/net/mac80211/mlme.c
- +++ b/net/mac80211/mlme.c
- @@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct
- }
-
- ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
- - sdata->vif.csa_active = true;
-
- mutex_lock(&local->chanctx_mtx);
- if (local->use_chanctx) {
- @@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct
- mutex_unlock(&local->chanctx_mtx);
-
- sdata->csa_chandef = csa_ie.chandef;
- + sdata->vif.csa_active = true;
-
- if (csa_ie.mode)
- ieee80211_stop_queues_by_reason(&local->hw,
- --- a/net/mac80211/chan.c
- +++ b/net/mac80211/chan.c
- @@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required(
- {
- struct ieee80211_sub_if_data *sdata;
-
- + lockdep_assert_held(&local->mtx);
- +
- rcu_read_lock();
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (sdata->radar_required) {
- --- a/net/mac80211/ibss.c
- +++ b/net/mac80211/ibss.c
- @@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st
- }
-
- mutex_lock(&local->mtx);
- - ieee80211_vif_release_channel(sdata);
- if (ieee80211_vif_use_channel(sdata, &chandef,
- ifibss->fixed_channel ?
- IEEE80211_CHANCTX_SHARED :
- @@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st
- mutex_unlock(&local->mtx);
- return;
- }
- + sdata->radar_required = radar_required;
- mutex_unlock(&local->mtx);
-
- memcpy(ifibss->bssid, bssid, ETH_ALEN);
- @@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st
- rcu_assign_pointer(ifibss->presp, presp);
- mgmt = (void *)presp->head;
-
- - sdata->radar_required = radar_required;
- sdata->vif.bss_conf.enable_beacon = true;
- sdata->vif.bss_conf.beacon_int = beacon_int;
- sdata->vif.bss_conf.basic_rates = basic_rates;
- @@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st
- presp->head_len, 0, GFP_KERNEL);
- cfg80211_put_bss(local->hw.wiphy, bss);
- netif_carrier_on(sdata->dev);
- - cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
- + cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
- }
-
- static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
- @@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct
- int err;
- u32 sta_flags;
-
- + sdata_assert_lock(sdata);
- +
- sta_flags = IEEE80211_STA_DISABLE_VHT;
- switch (ifibss->chandef.width) {
- case NL80211_CHAN_WIDTH_5:
- @@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req(
- memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN);
- ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa);
- IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
- +
- + /* avoid excessive retries for probe request to wildcard SSIDs */
- + if (pos[1] == 0)
- + IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
- +
- ieee80211_tx_skb(sdata, skb);
- }
-
- --- a/net/mac80211/mesh.c
- +++ b/net/mac80211/mesh.c
- @@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct
- if (!ifmsh->mesh_id)
- return false;
-
- + sdata_assert_lock(sdata);
- +
- sta_flags = IEEE80211_STA_DISABLE_VHT;
- switch (sdata->vif.bss_conf.chandef.width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
- --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
- @@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf
- struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- struct net_device *ndev = ifp->ndev;
- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
- + struct ieee80211_channel *chan;
- s32 err = 0;
-
- if (ifp->vif->mode == WL_MODE_AP) {
- @@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf
- } else if (brcmf_is_linkup(e)) {
- brcmf_dbg(CONN, "Linkup\n");
- if (brcmf_is_ibssmode(ifp->vif)) {
- + chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
- memcpy(profile->bssid, e->addr, ETH_ALEN);
- wl_inform_ibss(cfg, ndev, e->addr);
- - cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
- + cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
- clear_bit(BRCMF_VIF_STATUS_CONNECTING,
- &ifp->vif->sme_state);
- set_bit(BRCMF_VIF_STATUS_CONNECTED,
- --- a/drivers/net/wireless/libertas/cfg.c
- +++ b/drivers/net/wireless/libertas/cfg.c
- @@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri
- memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
- priv->wdev->ssid_len = params->ssid_len;
-
- - cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
- + cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
- + GFP_KERNEL);
-
- /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
- priv->connect_status = LBS_CONNECTED;
- --- a/drivers/net/wireless/mwifiex/cfg80211.c
- +++ b/drivers/net/wireless/mwifiex/cfg80211.c
- @@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy
- params->privacy);
- done:
- if (!ret) {
- - cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
- + cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
- + params->chandef.chan, GFP_KERNEL);
- dev_dbg(priv->adapter->dev,
- "info: joined/created adhoc network with bssid"
- " %pM successfully\n", priv->cfg_bssid);
- --- a/drivers/net/wireless/rndis_wlan.c
- +++ b/drivers/net/wireless/rndis_wlan.c
- @@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s
- bssid, req_ie, req_ie_len,
- resp_ie, resp_ie_len, GFP_KERNEL);
- } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
- - cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
- + cfg80211_ibss_joined(usbdev->net, bssid,
- + get_current_channel(usbdev, NULL),
- + GFP_KERNEL);
-
- kfree(info);
-
- --- a/net/wireless/ibss.c
- +++ b/net/wireless/ibss.c
- @@ -14,7 +14,8 @@
- #include "rdev-ops.h"
-
-
- -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
- +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
- + struct ieee80211_channel *channel)
- {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct cfg80211_bss *bss;
- @@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d
- if (!wdev->ssid_len)
- return;
-
- - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
- - wdev->ssid, wdev->ssid_len,
- + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
- WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
-
- if (WARN_ON(!bss))
- @@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
- #endif
- }
-
- -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
- +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
- + struct ieee80211_channel *channel, gfp_t gfp)
- {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- struct cfg80211_event *ev;
- unsigned long flags;
-
- - trace_cfg80211_ibss_joined(dev, bssid);
- + trace_cfg80211_ibss_joined(dev, bssid, channel);
- +
- + if (WARN_ON(!channel))
- + return;
-
- ev = kzalloc(sizeof(*ev), gfp);
- if (!ev)
- return;
-
- ev->type = EVENT_IBSS_JOINED;
- - memcpy(ev->cr.bssid, bssid, ETH_ALEN);
- + memcpy(ev->ij.bssid, bssid, ETH_ALEN);
- + ev->ij.channel = channel;
-
- spin_lock_irqsave(&wdev->event_lock, flags);
- list_add_tail(&ev->list, &wdev->event_list);
- @@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211
-
- wdev->ibss_fixed = params->channel_fixed;
- wdev->ibss_dfs_possible = params->userspace_handles_dfs;
- + wdev->chandef = params->chandef;
- #ifdef CPTCFG_CFG80211_WEXT
- wdev->wext.ibss.chandef = params->chandef;
- #endif
- @@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct
-
- wdev->current_bss = NULL;
- wdev->ssid_len = 0;
- + memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- #ifdef CPTCFG_CFG80211_WEXT
- if (!nowext)
- wdev->wext.ibss.ssid_len = 0;
- --- a/net/wireless/trace.h
- +++ b/net/wireless/trace.h
- @@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
- TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
- );
-
- -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
- - TP_PROTO(struct net_device *netdev, const u8 *addr),
- - TP_ARGS(netdev, addr)
- -);
- -
- DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
- TP_PROTO(struct net_device *netdev, const u8 *addr),
- TP_ARGS(netdev, addr)
- @@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r
- TP_ARGS(netdev, addr)
- );
-
- +TRACE_EVENT(cfg80211_ibss_joined,
- + TP_PROTO(struct net_device *netdev, const u8 *bssid,
- + struct ieee80211_channel *channel),
- + TP_ARGS(netdev, bssid, channel),
- + TP_STRUCT__entry(
- + NETDEV_ENTRY
- + MAC_ENTRY(bssid)
- + CHAN_ENTRY
- + ),
- + TP_fast_assign(
- + NETDEV_ASSIGN;
- + MAC_ASSIGN(bssid, bssid);
- + CHAN_ASSIGN(channel);
- + ),
- + TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
- + NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
- +);
- +
- TRACE_EVENT(cfg80211_probe_status,
- TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
- bool acked),
- --- a/net/wireless/util.c
- +++ b/net/wireless/util.c
- @@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct
- ev->dc.reason, true);
- break;
- case EVENT_IBSS_JOINED:
- - __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
- + __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
- + ev->ij.channel);
- break;
- }
- wdev_unlock(wdev);
- @@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct
- */
- mutex_lock_nested(&wdev_iter->mtx, 1);
- __acquire(wdev_iter->mtx);
- - cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
- + cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
- wdev_unlock(wdev_iter);
-
- switch (chmode) {
- --- a/net/wireless/chan.c
- +++ b/net/wireless/chan.c
- @@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- struct ieee80211_channel **chan,
- - enum cfg80211_chan_mode *chanmode)
- + enum cfg80211_chan_mode *chanmode,
- + u8 *radar_detect)
- {
- *chan = NULL;
- *chanmode = CHAN_MODE_UNDEFINED;
- @@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_
- !wdev->ibss_dfs_possible)
- ? CHAN_MODE_SHARED
- : CHAN_MODE_EXCLUSIVE;
- +
- + /* consider worst-case - IBSS can try to return to the
- + * original user-specified channel as creator */
- + if (wdev->ibss_dfs_possible)
- + *radar_detect |= BIT(wdev->chandef.width);
- return;
- }
- break;
- @@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_P2P_GO:
- if (wdev->cac_started) {
- - *chan = wdev->channel;
- + *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
- + *radar_detect |= BIT(wdev->chandef.width);
- } else if (wdev->beacon_interval) {
- - *chan = wdev->channel;
- + *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
- +
- + if (cfg80211_chandef_dfs_required(wdev->wiphy,
- + &wdev->chandef))
- + *radar_detect |= BIT(wdev->chandef.width);
- }
- return;
- case NL80211_IFTYPE_MESH_POINT:
- if (wdev->mesh_id_len) {
- - *chan = wdev->channel;
- + *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
- +
- + if (cfg80211_chandef_dfs_required(wdev->wiphy,
- + &wdev->chandef))
- + *radar_detect |= BIT(wdev->chandef.width);
- }
- return;
- case NL80211_IFTYPE_MONITOR:
- --- a/net/wireless/mesh.c
- +++ b/net/wireless/mesh.c
- @@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211
- if (!err) {
- memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
- wdev->mesh_id_len = setup->mesh_id_len;
- - wdev->channel = setup->chandef.chan;
- + wdev->chandef = setup->chandef;
- }
-
- return err;
- @@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg
- err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
- chandef->chan);
- if (!err)
- - wdev->channel = chandef->chan;
- + wdev->chandef = *chandef;
-
- return err;
- }
- @@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct
- err = rdev_leave_mesh(rdev, dev);
- if (!err) {
- wdev->mesh_id_len = 0;
- - wdev->channel = NULL;
- + memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- rdev_set_qos_map(rdev, dev, NULL);
- }
-
- --- a/net/wireless/mlme.c
- +++ b/net/wireless/mlme.c
- @@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic
- if (WARN_ON(!wdev->cac_started))
- return;
-
- - if (WARN_ON(!wdev->channel))
- + if (WARN_ON(!wdev->chandef.chan))
- return;
-
- switch (event) {
- --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
- +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
- @@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(
- break;
- }
- }
- +
- + if (is2GHz && !twiceMaxEdgePower)
- + twiceMaxEdgePower = 60;
- +
- return twiceMaxEdgePower;
- }
-
- --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
- +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
- @@ -23,10 +23,11 @@
- #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
- #define MAX_MAG_DELTA 11
- #define MAX_PHS_DELTA 10
- +#define MAXIQCAL 3
-
- struct coeff {
- - int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
- - int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
- + int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
- + int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
- int iqc_coeff[2];
- };
-
- @@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc
- if (q_q_coff > 63)
- q_q_coff = 63;
-
- - iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
- + iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
-
- ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[0]);
- @@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc
- if (q_q_coff > 63)
- q_q_coff = 63;
-
- - iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
- + iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
-
- ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
- chain_idx, iqc_coeff[1]);
- @@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc
- return true;
- }
-
- -static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
- +static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
- + int nmeasurement,
- int max_delta)
- {
- int mp_max = -64, max_idx = 0;
- @@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int
-
- /* find min/max mismatch across all calibrated gains */
- for (i = 0; i < nmeasurement; i++) {
- - if (mp_coeff[i] > mp_max) {
- - mp_max = mp_coeff[i];
- + if (mp_coeff[i][0] > mp_max) {
- + mp_max = mp_coeff[i][0];
- max_idx = i;
- - } else if (mp_coeff[i] < mp_min) {
- - mp_min = mp_coeff[i];
- + } else if (mp_coeff[i][0] < mp_min) {
- + mp_min = mp_coeff[i][0];
- min_idx = i;
- }
- }
-
- /* find average (exclude max abs value) */
- for (i = 0; i < nmeasurement; i++) {
- - if ((abs(mp_coeff[i]) < abs(mp_max)) ||
- - (abs(mp_coeff[i]) < abs(mp_min))) {
- - mp_avg += mp_coeff[i];
- + if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
- + (abs(mp_coeff[i][0]) < abs(mp_min))) {
- + mp_avg += mp_coeff[i][0];
- mp_count++;
- }
- }
- @@ -873,7 +875,7 @@ static void ar9003_hw_detect_outlier(int
- if (mp_count)
- mp_avg /= mp_count;
- else
- - mp_avg = mp_coeff[nmeasurement - 1];
- + mp_avg = mp_coeff[nmeasurement - 1][0];
-
- /* detect outlier */
- if (abs(mp_max - mp_min) > max_delta) {
- @@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int
- else
- outlier_idx = min_idx;
-
- - mp_coeff[outlier_idx] = mp_avg;
- + mp_coeff[outlier_idx][0] = mp_avg;
- }
- }
-
- -static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
- - struct coeff *coeff,
- - bool is_reusable)
- +static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah,
- + struct coeff *coeff,
- + bool is_reusable)
- {
- int i, im, nmeasurement;
- + int magnitude, phase;
- u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
- struct ath9k_hw_cal_data *caldata = ah->caldata;
-
- @@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_
- if (nmeasurement > MAX_MEASUREMENT)
- nmeasurement = MAX_MEASUREMENT;
-
- - /* detect outlier only if nmeasurement > 1 */
- - if (nmeasurement > 1) {
- - /* Detect magnitude outlier */
- - ar9003_hw_detect_outlier(coeff->mag_coeff[i],
- - nmeasurement, MAX_MAG_DELTA);
- -
- - /* Detect phase outlier */
- - ar9003_hw_detect_outlier(coeff->phs_coeff[i],
- - nmeasurement, MAX_PHS_DELTA);
- + /*
- + * Skip normal outlier detection for AR9550.
- + */
- + if (!AR_SREV_9550(ah)) {
- + /* detect outlier only if nmeasurement > 1 */
- + if (nmeasurement > 1) {
- + /* Detect magnitude outlier */
- + ar9003_hw_detect_outlier(coeff->mag_coeff[i],
- + nmeasurement,
- + MAX_MAG_DELTA);
- +
- + /* Detect phase outlier */
- + ar9003_hw_detect_outlier(coeff->phs_coeff[i],
- + nmeasurement,
- + MAX_PHS_DELTA);
- + }
- }
-
- for (im = 0; im < nmeasurement; im++) {
- + magnitude = coeff->mag_coeff[i][im][0];
- + phase = coeff->phs_coeff[i][im][0];
-
- - coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
- - ((coeff->phs_coeff[i][im] & 0x7f) << 7);
- + coeff->iqc_coeff[0] =
- + (phase & 0x7f) | ((magnitude & 0x7f) << 7);
-
- if ((im % 2) == 0)
- REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
- @@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru
- return true;
- }
-
- -static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
- +static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah,
- + struct coeff *coeff,
- + int i, int nmeasurement)
- +{
- + struct ath_common *common = ath9k_hw_common(ah);
- + int im, ix, iy, temp;
- +
- + for (im = 0; im < nmeasurement; im++) {
- + for (ix = 0; ix < MAXIQCAL - 1; ix++) {
- + for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
- + if (coeff->mag_coeff[i][im][iy] <
- + coeff->mag_coeff[i][im][ix]) {
- + temp = coeff->mag_coeff[i][im][ix];
- + coeff->mag_coeff[i][im][ix] =
- + coeff->mag_coeff[i][im][iy];
- + coeff->mag_coeff[i][im][iy] = temp;
- + }
- + if (coeff->phs_coeff[i][im][iy] <
- + coeff->phs_coeff[i][im][ix]) {
- + temp = coeff->phs_coeff[i][im][ix];
- + coeff->phs_coeff[i][im][ix] =
- + coeff->phs_coeff[i][im][iy];
- + coeff->phs_coeff[i][im][iy] = temp;
- + }
- + }
- + }
- + coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
- + coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
- +
- + ath_dbg(common, CALIBRATE,
- + "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
- + i, im,
- + coeff->mag_coeff[i][im][0],
- + coeff->phs_coeff[i][im][0]);
- + }
- +}
- +
- +static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
- + struct coeff *coeff,
- + int iqcal_idx,
- + int nmeasurement)
- +{
- + int i;
- +
- + if ((iqcal_idx + 1) != MAXIQCAL)
- + return false;
- +
- + for (i = 0; i < AR9300_MAX_CHAINS; i++) {
- + __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
- + }
- +
- + return true;
- +}
- +
- +static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
- + int iqcal_idx,
- + bool is_reusable)
- {
- struct ath_common *common = ath9k_hw_common(ah);
- const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
- @@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro
- AR_PHY_CHAN_INFO_TAB_1,
- AR_PHY_CHAN_INFO_TAB_2,
- };
- - struct coeff coeff;
- + static struct coeff coeff;
- s32 iq_res[6];
- int i, im, j;
- - int nmeasurement;
- + int nmeasurement = 0;
- + bool outlier_detect = true;
-
- for (i = 0; i < AR9300_MAX_CHAINS; i++) {
- if (!(ah->txchainmask & (1 << i)))
- @@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro
- goto tx_iqcal_fail;
- }
-
- - coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
- - coeff.phs_coeff[i][im] =
- + coeff.phs_coeff[i][im][iqcal_idx] =
- + coeff.iqc_coeff[0] & 0x7f;
- + coeff.mag_coeff[i][im][iqcal_idx] =
- (coeff.iqc_coeff[0] >> 7) & 0x7f;
-
- - if (coeff.mag_coeff[i][im] > 63)
- - coeff.mag_coeff[i][im] -= 128;
- - if (coeff.phs_coeff[i][im] > 63)
- - coeff.phs_coeff[i][im] -= 128;
- + if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
- + coeff.mag_coeff[i][im][iqcal_idx] -= 128;
- + if (coeff.phs_coeff[i][im][iqcal_idx] > 63)
- + coeff.phs_coeff[i][im][iqcal_idx] -= 128;
- }
- }
- - ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
- +
- + if (AR_SREV_9550(ah))
- + outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff,
- + iqcal_idx, nmeasurement);
- + if (outlier_detect)
- + ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable);
-
- return;
-
- @@ -1409,7 +1484,7 @@ skip_tx_iqcal:
- }
-
- if (txiqcal_done)
- - ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
- + ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
- else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
- ar9003_hw_tx_iq_cal_reload(ah);
-
- @@ -1455,14 +1530,38 @@ skip_tx_iqcal:
- return true;
- }
-
- +static bool do_ar9003_agc_cal(struct ath_hw *ah)
- +{
- + struct ath_common *common = ath9k_hw_common(ah);
- + bool status;
- +
- + REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- + REG_READ(ah, AR_PHY_AGC_CONTROL) |
- + AR_PHY_AGC_CONTROL_CAL);
- +
- + status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
- + AR_PHY_AGC_CONTROL_CAL,
- + 0, AH_WAIT_TIMEOUT);
- + if (!status) {
- + ath_dbg(common, CALIBRATE,
- + "offset calibration failed to complete in %d ms,"
- + "noisy environment?\n",
- + AH_WAIT_TIMEOUT / 1000);
- + return false;
- + }
- +
- + return true;
- +}
- +
- static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
- struct ath9k_channel *chan)
- {
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_hw_cal_data *caldata = ah->caldata;
- bool txiqcal_done = false;
- - bool is_reusable = true, status = true;
- + bool status = true;
- bool run_agc_cal = false, sep_iq_cal = false;
- + int i = 0;
-
- /* Use chip chainmask only for calibration */
- ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
- @@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc
- * AGC calibration. Specifically, AR9550 in SoC chips.
- */
- if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
- - txiqcal_done = true;
- + if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
- + AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
- + txiqcal_done = true;
- + } else {
- + txiqcal_done = false;
- + }
- run_agc_cal = true;
- } else {
- sep_iq_cal = true;
- @@ -1512,27 +1616,37 @@ skip_tx_iqcal:
- if (AR_SREV_9330_11(ah))
- ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan));
-
- - /* Calibrate the AGC */
- - REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- - REG_READ(ah, AR_PHY_AGC_CONTROL) |
- - AR_PHY_AGC_CONTROL_CAL);
- -
- - /* Poll for offset calibration complete */
- - status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
- - AR_PHY_AGC_CONTROL_CAL,
- - 0, AH_WAIT_TIMEOUT);
- - }
- + /*
- + * For non-AR9550 chips, we just trigger AGC calibration
- + * in the HW, poll for completion and then process
- + * the results.
- + *
- + * For AR955x, we run it multiple times and use
- + * median IQ correction.
- + */
- + if (!AR_SREV_9550(ah)) {
- + status = do_ar9003_agc_cal(ah);
- + if (!status)
- + return false;
-
- - if (!status) {
- - ath_dbg(common, CALIBRATE,
- - "offset calibration failed to complete in %d ms; noisy environment?\n",
- - AH_WAIT_TIMEOUT / 1000);
- - return false;
- + if (txiqcal_done)
- + ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
- + } else {
- + if (!txiqcal_done) {
- + status = do_ar9003_agc_cal(ah);
- + if (!status)
- + return false;
- + } else {
- + for (i = 0; i < MAXIQCAL; i++) {
- + status = do_ar9003_agc_cal(ah);
- + if (!status)
- + return false;
- + ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
- + }
- + }
- + }
- }
-
- - if (txiqcal_done)
- - ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
- -
- /* Revert chainmask to runtime parameters */
- ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
-
- --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
- +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
- @@ -15,6 +15,8 @@
- #ifndef RTL8187_H
- #define RTL8187_H
-
- +#include <linux/cache.h>
- +
- #include "rtl818x.h"
- #include "leds.h"
-
- @@ -139,7 +141,10 @@ struct rtl8187_priv {
- u8 aifsn[4];
- u8 rfkill_mask;
- struct {
- - __le64 buf;
- + union {
- + __le64 buf;
- + u8 dummy1[L1_CACHE_BYTES];
- + } ____cacheline_aligned;
- struct sk_buff_head queue;
- } b_tx_status; /* This queue is used by both -b and non-b devices */
- struct mutex io_mutex;
- @@ -147,7 +152,8 @@ struct rtl8187_priv {
- u8 bits8;
- __le16 bits16;
- __le32 bits32;
- - } *io_dmabuf;
- + u8 dummy2[L1_CACHE_BYTES];
- + } *io_dmabuf ____cacheline_aligned;
- bool rfkill_off;
- u16 seqno;
- };
- --- a/net/mac80211/wme.c
- +++ b/net/mac80211/wme.c
- @@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80
- return IEEE80211_AC_BE;
- }
-
- + if (skb->protocol == sdata->control_port_protocol) {
- + skb->priority = 7;
- + return ieee80211_downgrade_queue(sdata, skb);
- + }
- +
- /* use the data classifier to determine what 802.1d tag the
- * data frame has */
- rcu_read_lock();
- --- a/drivers/net/wireless/ath/ath9k/xmit.c
- +++ b/drivers/net/wireless/ath/ath9k/xmit.c
- @@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
- for (tidno = 0, tid = &an->tid[tidno];
- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-
- - if (!tid->sched)
- - continue;
- -
- ac = tid->ac;
- txq = ac->txq;
-
- ath_txq_lock(sc, txq);
-
- + if (!tid->sched) {
- + ath_txq_unlock(sc, txq);
- + continue;
- + }
- +
- buffered = ath_tid_has_buffered(tid);
-
- tid->sched = false;
- @@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw
- txq->stopped = true;
- }
-
- + if (txctl->an)
- + tid = ath_get_skb_tid(sc, txctl->an, skb);
- +
- if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
- ath_txq_unlock(sc, txq);
- txq = sc->tx.uapsdq;
- ath_txq_lock(sc, txq);
- } else if (txctl->an &&
- ieee80211_is_data_present(hdr->frame_control)) {
- - tid = ath_get_skb_tid(sc, txctl->an, skb);
- -
- WARN_ON(tid->ac->txq != txctl->txq);
-
- if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
- --- a/drivers/net/wireless/ath/ath9k/init.c
- +++ b/drivers/net/wireless/ath/ath9k/init.c
- @@ -943,6 +943,7 @@ static void ath9k_set_hw_capab(struct at
- hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
- hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
- + hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
-
- hw->queues = 4;
- hw->max_rates = 4;
- --- a/net/mac80211/ieee80211_i.h
- +++ b/net/mac80211/ieee80211_i.h
- @@ -1700,14 +1700,8 @@ void ieee80211_stop_queue_by_reason(stru
- void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
- void ieee80211_add_pending_skb(struct ieee80211_local *local,
- struct sk_buff *skb);
- -void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
- - struct sk_buff_head *skbs,
- - void (*fn)(void *data), void *data);
- -static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
- - struct sk_buff_head *skbs)
- -{
- - ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
- -}
- +void ieee80211_add_pending_skbs(struct ieee80211_local *local,
- + struct sk_buff_head *skbs);
- void ieee80211_flush_queues(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata);
-
- --- a/net/mac80211/sta_info.c
- +++ b/net/mac80211/sta_info.c
- @@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee
- return -ENOENT;
- }
-
- -static void cleanup_single_sta(struct sta_info *sta)
- +static void __cleanup_single_sta(struct sta_info *sta)
- {
- int ac, i;
- struct tid_ampdu_tx *tid_tx;
- @@ -99,7 +99,8 @@ static void cleanup_single_sta(struct st
- struct ieee80211_local *local = sdata->local;
- struct ps_data *ps;
-
- - if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
- + if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
- + test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
- if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
- sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- ps = &sdata->bss->ps;
- @@ -109,6 +110,7 @@ static void cleanup_single_sta(struct st
- return;
-
- clear_sta_flag(sta, WLAN_STA_PS_STA);
- + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
- atomic_dec(&ps->num_sta_ps);
- sta_info_recalc_tim(sta);
- @@ -139,7 +141,14 @@ static void cleanup_single_sta(struct st
- ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
- kfree(tid_tx);
- }
- +}
-
- +static void cleanup_single_sta(struct sta_info *sta)
- +{
- + struct ieee80211_sub_if_data *sdata = sta->sdata;
- + struct ieee80211_local *local = sdata->local;
- +
- + __cleanup_single_sta(sta);
- sta_info_free(local, sta);
- }
-
- @@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
- rcu_read_unlock();
-
- spin_lock_init(&sta->lock);
- + spin_lock_init(&sta->ps_lock);
- INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
- INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
- mutex_init(&sta->ampdu_mlme.mtx);
- @@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct
- goto out_err;
- }
-
- - /* notify driver */
- - err = sta_info_insert_drv_state(local, sdata, sta);
- - if (err)
- - goto out_err;
- -
- local->num_sta++;
- local->sta_generation++;
- smp_mb();
-
- + /* simplify things and don't accept BA sessions yet */
- + set_sta_flag(sta, WLAN_STA_BLOCK_BA);
- +
- /* make the station visible */
- sta_info_hash_add(local, sta);
-
- list_add_rcu(&sta->list, &local->sta_list);
-
- + /* notify driver */
- + err = sta_info_insert_drv_state(local, sdata, sta);
- + if (err)
- + goto out_remove;
- +
- set_sta_flag(sta, WLAN_STA_INSERTED);
- + /* accept BA sessions now */
- + clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
-
- ieee80211_recalc_min_chandef(sdata);
- ieee80211_sta_debugfs_add(sta);
- @@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct
- mesh_accept_plinks_update(sdata);
-
- return 0;
- + out_remove:
- + sta_info_hash_del(local, sta);
- + list_del_rcu(&sta->list);
- + local->num_sta--;
- + synchronize_net();
- + __cleanup_single_sta(sta);
- out_err:
- mutex_unlock(&local->sta_mtx);
- rcu_read_lock();
- @@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta
- }
- EXPORT_SYMBOL(ieee80211_find_sta);
-
- -static void clear_sta_ps_flags(void *_sta)
- +/* powersave support code */
- +void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
- {
- - struct sta_info *sta = _sta;
- struct ieee80211_sub_if_data *sdata = sta->sdata;
- + struct ieee80211_local *local = sdata->local;
- + struct sk_buff_head pending;
- + int filtered = 0, buffered = 0, ac;
- + unsigned long flags;
- struct ps_data *ps;
-
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- @@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st
- else
- return;
-
- - clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- - if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
- - atomic_dec(&ps->num_sta_ps);
- -}
- -
- -/* powersave support code */
- -void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
- -{
- - struct ieee80211_sub_if_data *sdata = sta->sdata;
- - struct ieee80211_local *local = sdata->local;
- - struct sk_buff_head pending;
- - int filtered = 0, buffered = 0, ac;
- - unsigned long flags;
- -
- clear_sta_flag(sta, WLAN_STA_SP);
-
- BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
- @@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str
-
- skb_queue_head_init(&pending);
-
- + /* sync with ieee80211_tx_h_unicast_ps_buf */
- + spin_lock(&sta->ps_lock);
- /* Send all buffered frames to the station */
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
- int count = skb_queue_len(&pending), tmp;
- @@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str
- buffered += tmp - count;
- }
-
- - ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
- + ieee80211_add_pending_skbs(local, &pending);
- + clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
- + clear_sta_flag(sta, WLAN_STA_PS_STA);
- + spin_unlock(&sta->ps_lock);
- +
- + atomic_dec(&ps->num_sta_ps);
-
- /* This station just woke up and isn't aware of our SMPS state */
- if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
- --- a/net/mac80211/sta_info.h
- +++ b/net/mac80211/sta_info.h
- @@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat {
- * @drv_unblock_wk: used for driver PS unblocking
- * @listen_interval: listen interval of this station, when we're acting as AP
- * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
- + * @ps_lock: used for powersave (when mac80211 is the AP) related locking
- * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
- * when it leaves power saving state or polls
- * @tx_filtered: buffers (per AC) of frames we already tried to
- @@ -356,10 +357,8 @@ struct sta_info {
- /* use the accessors defined below */
- unsigned long _flags;
-
- - /*
- - * STA powersave frame queues, no more than the internal
- - * locking required.
- - */
- + /* STA powersave lock and frame queues */
- + spinlock_t ps_lock;
- struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
- struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
- unsigned long driver_buffered_tids;
- --- a/net/mac80211/util.c
- +++ b/net/mac80211/util.c
- @@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie
- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
- }
-
- -void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
- - struct sk_buff_head *skbs,
- - void (*fn)(void *data), void *data)
- +void ieee80211_add_pending_skbs(struct ieee80211_local *local,
- + struct sk_buff_head *skbs)
- {
- struct ieee80211_hw *hw = &local->hw;
- struct sk_buff *skb;
- @@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc
- __skb_queue_tail(&local->pending[queue], skb);
- }
-
- - if (fn)
- - fn(data);
- -
- for (i = 0; i < hw->queues; i++)
- __ieee80211_wake_queue(hw, i,
- IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
- --- a/net/wireless/reg.c
- +++ b/net/wireless/reg.c
- @@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regu
- return;
- case NL80211_REGDOM_SET_BY_USER:
- treatment = reg_process_hint_user(reg_request);
- - if (treatment == REG_REQ_OK ||
- + if (treatment == REG_REQ_IGNORE ||
- treatment == REG_REQ_ALREADY_SET)
- return;
- schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
- @@ -866,6 +866,12 @@ static ssize_t read_file_reset(struct fi
- "%17s: %2d\n", "PLL RX Hang",
- sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
- len += scnprintf(buf + len, sizeof(buf) - len,
- + "%17s: %2d\n", "MAC Hang",
- + sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
- + len += scnprintf(buf + len, sizeof(buf) - len,
- + "%17s: %2d\n", "Stuck Beacon",
- + sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
- + len += scnprintf(buf + len, sizeof(buf) - len,
- "%17s: %2d\n", "MCI Reset",
- sc->debug.stats.reset[RESET_TYPE_MCI]);
-
- --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
- +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
- @@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct
-
- if (IS_CHAN_A_FAST_CLOCK(ah, chan))
- rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
- - if (IS_CHAN_QUARTER_RATE(chan))
- - rfMode |= AR_PHY_MODE_QUARTER;
- - if (IS_CHAN_HALF_RATE(chan))
- - rfMode |= AR_PHY_MODE_HALF;
-
- if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
- REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
- --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
- +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
- @@ -706,6 +706,7 @@ ath5k_get_survey(struct ieee80211_hw *hw
- survey->channel = conf->chandef.chan;
- survey->noise = ah->ah_noise_floor;
- survey->filled = SURVEY_INFO_NOISE_DBM |
- + SURVEY_INFO_IN_USE |
- SURVEY_INFO_CHANNEL_TIME |
- SURVEY_INFO_CHANNEL_TIME_BUSY |
- SURVEY_INFO_CHANNEL_TIME_RX |
- --- a/drivers/net/wireless/ath/ath9k/recv.c
- +++ b/drivers/net/wireless/ath/ath9k/recv.c
- @@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx
- return NULL;
-
- /*
- - * mark descriptor as zero-length and set the 'more'
- - * flag to ensure that both buffers get discarded
- + * Re-check previous descriptor, in case it has been filled
- + * in the mean time.
- */
- - rs->rs_datalen = 0;
- - rs->rs_more = true;
- + ret = ath9k_hw_rxprocdesc(ah, ds, rs);
- + if (ret == -EINPROGRESS) {
- + /*
- + * mark descriptor as zero-length and set the 'more'
- + * flag to ensure that both buffers get discarded
- + */
- + rs->rs_datalen = 0;
- + rs->rs_more = true;
- + }
- }
-
- list_del(&bf->list);
- @@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_hdr *hdr;
- bool discard_current = sc->rx.discard_next;
- - int ret = 0;
-
- /*
- * Discard corrupt descriptors which are marked in
- * ath_get_next_rx_buf().
- */
- - sc->rx.discard_next = rx_stats->rs_more;
- if (discard_current)
- - return -EINVAL;
- + goto corrupt;
- +
- + sc->rx.discard_next = false;
-
- /*
- * Discard zero-length packets.
- */
- if (!rx_stats->rs_datalen) {
- RX_STAT_INC(rx_len_err);
- - return -EINVAL;
- + goto corrupt;
- }
-
- - /*
- - * rs_status follows rs_datalen so if rs_datalen is too large
- - * we can take a hint that hardware corrupted it, so ignore
- - * those frames.
- - */
- + /*
- + * rs_status follows rs_datalen so if rs_datalen is too large
- + * we can take a hint that hardware corrupted it, so ignore
- + * those frames.
- + */
- if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
- RX_STAT_INC(rx_len_err);
- - return -EINVAL;
- + goto corrupt;
- }
-
- /* Only use status info from the last fragment */
- @@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc
- * This is different from the other corrupt descriptor
- * condition handled above.
- */
- - if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
- - ret = -EINVAL;
- - goto exit;
- - }
- + if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
- + goto corrupt;
-
- hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
-
- @@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struc
- if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
- RX_STAT_INC(rx_spectral);
-
- - ret = -EINVAL;
- - goto exit;
- + return -EINVAL;
- }
-
- /*
- * everything but the rate is checked here, the rate check is done
- * separately to avoid doing two lookups for a rate for each frame.
- */
- - if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
- - ret = -EINVAL;
- - goto exit;
- - }
- + if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
- + return -EINVAL;
-
- if (ath_is_mybeacon(common, hdr)) {
- RX_STAT_INC(rx_beacons);
- @@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc
- /*
- * This shouldn't happen, but have a safety check anyway.
- */
- - if (WARN_ON(!ah->curchan)) {
- - ret = -EINVAL;
- - goto exit;
- - }
- + if (WARN_ON(!ah->curchan))
- + return -EINVAL;
-
- - if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
- - ret =-EINVAL;
- - goto exit;
- - }
- + if (ath9k_process_rate(common, hw, rx_stats, rx_status))
- + return -EINVAL;
-
- ath9k_process_rssi(common, hw, rx_stats, rx_status);
-
- @@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc
- sc->rx.num_pkts++;
- #endif
-
- -exit:
- - sc->rx.discard_next = false;
- - return ret;
- + return 0;
- +
- +corrupt:
- + sc->rx.discard_next = rx_stats->rs_more;
- + return -EINVAL;
- }
-
- static void ath9k_rx_skb_postprocess(struct ath_common *common,
- --- a/drivers/net/wireless/ath/ath9k/ani.c
- +++ b/drivers/net/wireless/ath/ath9k/ani.c
- @@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct
- if (ah->opmode == NL80211_IFTYPE_STATION &&
- BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
- weak_sig = true;
- -
- /*
- - * OFDM Weak signal detection is always enabled for AP mode.
- + * Newer chipsets are better at dealing with high PHY error counts -
- + * keep weak signal detection enabled when no RSSI threshold is
- + * available to determine if it is needed (mode != STA)
- */
- - if (ah->opmode != NL80211_IFTYPE_AP &&
- - aniState->ofdmWeakSigDetect != weak_sig) {
- - ath9k_hw_ani_control(ah,
- - ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
- - entry_ofdm->ofdm_weak_signal_on);
- - }
- + else if (AR_SREV_9300_20_OR_LATER(ah) &&
- + ah->opmode != NL80211_IFTYPE_STATION)
- + weak_sig = true;
- +
- + /* Older chipsets are more sensitive to high PHY error counts */
- + else if (!AR_SREV_9300_20_OR_LATER(ah) &&
- + aniState->ofdmNoiseImmunityLevel >= 8)
- + weak_sig = false;
- +
- + if (aniState->ofdmWeakSigDetect != weak_sig)
- + ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
- + weak_sig);
- +
- + if (!AR_SREV_9300_20_OR_LATER(ah))
- + return;
-
- if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
- @@ -483,10 +493,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah
-
- ath_dbg(common, ANI, "Initialize ANI\n");
-
- - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
- - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
- - ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
- - ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
- + if (AR_SREV_9300_20_OR_LATER(ah)) {
- + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
- + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
- + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
- + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
- + } else {
- + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
- + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
- + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
- + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
- + }
-
- ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
- ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
- --- a/drivers/net/wireless/ath/ath9k/ani.h
- +++ b/drivers/net/wireless/ath/ath9k/ani.h
- @@ -22,12 +22,16 @@
- /* units are errors per second */
- #define ATH9K_ANI_OFDM_TRIG_HIGH 3500
- #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
- +#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
-
- #define ATH9K_ANI_OFDM_TRIG_LOW 400
- #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
- +#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
-
- #define ATH9K_ANI_CCK_TRIG_HIGH 600
- +#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
- #define ATH9K_ANI_CCK_TRIG_LOW 300
- +#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
-
- #define ATH9K_ANI_SPUR_IMMUNE_LVL 3
- #define ATH9K_ANI_FIRSTEP_LVL 2
|