~ubuntu-branches/ubuntu/jaunty/ndiswrapper/jaunty

« back to all changes in this revision

Viewing changes to driver/ndis.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2008-11-21 14:17:35 UTC
  • mfrom: (1.2.11 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20081121141735-hzymcfoy3up8hego
Tags: 1.53-2ubuntu1
* Merge with Debian; remaining changes:
  - Build for lpia.
  - debian/control:
    + Update description to point out that the kernel source package is
      not required with the standard Ubuntu kernel.
    + Change the Maintainer address.
  - debian/control:
    + Drop ndiswrapper-source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "loader.h"
21
21
#include <linux/kernel_stat.h>
22
22
#include <asm/dma.h>
 
23
#include "ndis_exports.h"
23
24
 
24
25
#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE
25
26
#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE
32
33
workqueue_struct_t *ndis_wq;
33
34
static struct nt_thread *ndis_worker_thread;
34
35
 
35
 
extern struct semaphore loader_mutex;
36
 
 
37
36
static void *ndis_get_routine_address(char *name);
38
37
 
39
38
wstdcall void WIN_FUNC(NdisInitializeWrapper,4)
56
55
{
57
56
        int min_length;
58
57
        struct wrap_driver *wrap_driver;
59
 
        struct wrap_ndis_driver *ndis_driver;
 
58
        struct ndis_driver *ndis_driver;
60
59
 
61
60
        min_length = ((char *)&mp->co_create_vc) - ((char *)mp);
62
61
 
551
550
        (NDIS_STATUS *status, void **addr, UINT *len,
552
551
         struct ndis_mp_block *nmb)
553
552
{
554
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
553
        struct ndis_device *wnd = nmb->wnd;
555
554
        struct ndis_configuration_parameter *param;
556
555
        struct unicode_string key;
557
556
        struct ansi_string ansi;
662
661
        (struct ndis_mp_block *nmb, void *mp_ctx,
663
662
         UINT hangcheck_interval, UINT attributes, ULONG adaptertype)
664
663
{
665
 
        struct wrap_ndis_device *wnd;
 
664
        struct ndis_device *wnd;
666
665
 
667
666
        ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval,
668
667
               attributes, adaptertype);
765
764
        (NDIS_STATUS *status, struct ndis_mp_block *nmb,
766
765
         NDIS_RESOURCE_LIST *resource_list, UINT *size)
767
766
{
768
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
767
        struct ndis_device *wnd = nmb->wnd;
769
768
        NDIS_RESOURCE_LIST *list;
770
769
        UINT resource_length;
771
770
 
803
802
        (struct ndis_mp_block *nmb, ULONG slot_number,
804
803
         NDIS_RESOURCE_LIST **resources)
805
804
{
806
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
805
        struct ndis_device *wnd = nmb->wnd;
807
806
 
808
807
        ENTER2("%p, %p", wnd, wnd->wd->resource_list);
809
808
        *resources = &wnd->wd->resource_list->list->partial_resource_list;
811
810
}
812
811
 
813
812
wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4)
814
 
        (void **virt, struct ndis_mp_block *nmb,
 
813
        (void __iomem **virt, struct ndis_mp_block *nmb,
815
814
         NDIS_PHY_ADDRESS phy_addr, UINT len)
816
815
{
817
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
816
        struct ndis_device *wnd = nmb->wnd;
818
817
 
819
818
        ENTER2("%Lx, %d", phy_addr, len);
820
819
        *virt = MmMapIoSpace(phy_addr, len, MmCached);
829
828
}
830
829
 
831
830
wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3)
832
 
        (struct ndis_mp_block *nmb, void *virt, UINT len)
 
831
        (struct ndis_mp_block *nmb, void __iomem *virt, UINT len)
833
832
{
834
833
        ENTER2("%p, %d", virt, len);
835
834
        MmUnmapIoSpace(virt, len);
937
936
        (struct ndis_mp_block *nmb, UINT dmachan,
938
937
         NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size)
939
938
{
940
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
939
        struct ndis_device *wnd = nmb->wnd;
941
940
 
942
941
        ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size);
943
942
        if (wnd->dma_map_count > 0) {
989
988
wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1)
990
989
        (struct ndis_mp_block *nmb)
991
990
{
992
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
991
        struct ndis_device *wnd = nmb->wnd;
993
992
        int i;
994
993
 
995
994
        ENTER2("wnd: %p", wnd);
1013
1012
         ULONG index, BOOLEAN write_to_dev,
1014
1013
         struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size)
1015
1014
{
1016
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1015
        struct ndis_device *wnd = nmb->wnd;
1017
1016
 
1018
1017
        ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count);
1019
1018
        if (unlikely(wnd->sg_dma_size || !write_to_dev ||
1051
1050
wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3)
1052
1051
        (struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index)
1053
1052
{
1054
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1053
        struct ndis_device *wnd = nmb->wnd;
1055
1054
 
1056
1055
        ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count);
1057
1056
 
1100
1099
 
1101
1100
wstdcall void alloc_shared_memory_async(void *arg1, void *arg2)
1102
1101
{
1103
 
        struct wrap_ndis_device *wnd;
 
1102
        struct ndis_device *wnd;
1104
1103
        struct alloc_shared_mem *alloc_shared_mem;
1105
1104
        struct miniport *mp;
1106
1105
        void *virt;
1124
1123
wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4)
1125
1124
        (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx)
1126
1125
{
1127
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1126
        struct ndis_device *wnd = nmb->wnd;
1128
1127
        struct alloc_shared_mem *alloc_shared_mem;
1129
1128
 
1130
1129
        ENTER3("wnd: %p", wnd);
1692
1691
        (NDIS_STATUS *status, struct ndis_mp_block *nmb,
1693
1692
         struct ndis_packet *packet)
1694
1693
{
1695
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1694
        struct ndis_device *wnd = nmb->wnd;
1696
1695
        struct miniport *mp;
1697
1696
        KIRQL irql;
1698
1697
 
1839
1838
wstdcall void WIN_FUNC(NdisMRegisterAdapterShutdownHandler,3)
1840
1839
        (struct ndis_mp_block *nmb, void *ctx, void *func)
1841
1840
{
1842
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1841
        struct ndis_device *wnd = nmb->wnd;
1843
1842
        ENTER1("%p", func);
1844
1843
        wnd->wd->driver->ndis_driver->mp.shutdown = func;
1845
1844
        wnd->shutdown_ctx = ctx;
1848
1847
wstdcall void WIN_FUNC(NdisMDeregisterAdapterShutdownHandler,1)
1849
1848
        (struct ndis_mp_block *nmb)
1850
1849
{
1851
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1850
        struct ndis_device *wnd = nmb->wnd;
1852
1851
        wnd->wd->driver->ndis_driver->mp.shutdown = NULL;
1853
1852
        wnd->shutdown_ctx = NULL;
1854
1853
}
1862
1861
wstdcall void deserialized_irq_handler(struct kdpc *kdpc, void *ctx,
1863
1862
                                       void *arg1, void *arg2)
1864
1863
{
1865
 
        struct wrap_ndis_device *wnd = ctx;
 
1864
        struct ndis_device *wnd = ctx;
1866
1865
        ndis_interrupt_handler irq_handler = arg1;
1867
1866
        struct miniport *mp = arg2;
1868
1867
 
1878
1877
wstdcall void serialized_irq_handler(struct kdpc *kdpc, void *ctx,
1879
1878
                                     void *arg1, void *arg2)
1880
1879
{
1881
 
        struct wrap_ndis_device *wnd = ctx;
 
1880
        struct ndis_device *wnd = ctx;
1882
1881
        ndis_interrupt_handler irq_handler = arg1;
1883
1882
 
1884
1883
        TRACE6("%p, %p, %p", wnd, irq_handler, arg2);
1893
1892
wstdcall BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx)
1894
1893
{
1895
1894
        struct ndis_mp_interrupt *mp_interrupt = ctx;
1896
 
        struct wrap_ndis_device *wnd = mp_interrupt->nmb->wnd;
 
1895
        struct ndis_device *wnd = mp_interrupt->nmb->wnd;
1897
1896
        BOOLEAN recognized, queue_handler;
1898
1897
 
1899
1898
        TRACE6("%p", wnd);
1926
1925
         struct ndis_mp_block *nmb, UINT vector, UINT level,
1927
1926
         BOOLEAN req_isr, BOOLEAN shared, enum kinterrupt_mode mode)
1928
1927
{
1929
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
1928
        struct ndis_device *wnd = nmb->wnd;
1930
1929
        struct miniport *mp;
1931
1930
 
1932
1931
        ENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d",
2009
2008
wstdcall void WIN_FUNC(NdisMIndicateStatus,4)
2010
2009
        (struct ndis_mp_block *nmb, NDIS_STATUS status, void *buf, UINT len)
2011
2010
{
2012
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2011
        struct ndis_device *wnd = nmb->wnd;
2013
2012
        struct ndis_status_indication *si;
2014
 
        struct ndis_auth_req *auth_req;
2015
 
        struct ndis_radio_status_indication *radio_status;
2016
2013
 
2017
2014
        ENTER2("status=0x%x len=%d", status, len);
2018
2015
        switch (status) {
2022
2019
                if (netif_queue_stopped(wnd->net_dev))
2023
2020
                        netif_wake_queue(wnd->net_dev);
2024
2021
                if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
2025
 
                        set_bit(LINK_STATUS_ON, &wnd->wrap_ndis_pending_work);
2026
 
                        schedule_wrapndis_work(&wnd->wrap_ndis_work);
 
2022
                        set_bit(LINK_STATUS_ON, &wnd->ndis_pending_work);
 
2023
                        schedule_wrapndis_work(&wnd->ndis_work);
2027
2024
                }
2028
2025
                break;
2029
2026
        case NDIS_STATUS_MEDIA_DISCONNECT:
2032
2029
                wnd->tx_ok = 0;
2033
2030
                if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
2034
2031
                        memset(&wnd->essid, 0, sizeof(wnd->essid));
2035
 
                        set_bit(LINK_STATUS_OFF, &wnd->wrap_ndis_pending_work);
2036
 
                        schedule_wrapndis_work(&wnd->wrap_ndis_work);
 
2032
                        set_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work);
 
2033
                        schedule_wrapndis_work(&wnd->ndis_work);
2037
2034
                }
2038
2035
                break;
2039
2036
        case NDIS_STATUS_MEDIA_SPECIFIC_INDICATION:
2050
2047
                        len -= sizeof(*si);
2051
2048
                        while (len > 0) {
2052
2049
                                int pairwise_error = 0, group_error = 0;
2053
 
                                auth_req = (struct ndis_auth_req *)buf;
 
2050
                                struct ndis_auth_req *auth_req =
 
2051
                                        (struct ndis_auth_req *)buf;
2054
2052
                                TRACE1(MACSTRSEP, MAC2STR(auth_req->bssid));
2055
2053
                                if (auth_req->flags & 0x01)
2056
2054
                                        TRACE2("reauth request");
2064
2062
                                        group_error = 1;
2065
2063
                                        TRACE2("group_error");
2066
2064
                                }
2067
 
#if WIRELESS_EXT > 17
2068
2065
                                if (pairwise_error || group_error) {
2069
2066
                                        union iwreq_data wrqu;
2070
2067
                                        struct iw_michaelmicfailure micfailure;
2084
2081
                                                            IWEVMICHAELMICFAILURE,
2085
2082
                                                            &wrqu, (u8 *)&micfailure);
2086
2083
                                }
2087
 
#endif
2088
2084
                                len -= auth_req->length;
2089
2085
                                buf = (char *)buf + auth_req->length;
2090
2086
                        }
2107
2103
                        TRACE2("PMKID ver %d num_cand %d",
2108
2104
                               cand->version, cand->num_candidates);
2109
2105
                        for (i = 0; i < cand->num_candidates; i++) {
2110
 
#if WIRELESS_EXT > 17
2111
2106
                                struct iw_pmkid_cand pcand;
2112
2107
                                union iwreq_data wrqu;
2113
 
#endif
2114
2108
                                struct ndis_pmkid_candidate *c =
2115
2109
                                        &cand->candidates[i];
2116
2110
                                if ((u8 *)(c + 1) > end) {
2119
2113
                                }
2120
2114
                                TRACE2("%ld: " MACSTRSEP " 0x%x",
2121
2115
                                       i, MAC2STR(c->bssid), c->flags);
2122
 
#if WIRELESS_EXT > 17
2123
2116
                                memset(&pcand, 0, sizeof(pcand));
2124
2117
                                if (c->flags & 0x01)
2125
2118
                                        pcand.flags |= IW_PMKID_CAND_PREAUTH;
2130
2123
                                wrqu.data.length = sizeof(pcand);
2131
2124
                                wireless_send_event(wnd->net_dev, IWEVPMKIDCAND,
2132
2125
                                                    &wrqu, (u8 *)&pcand);
2133
 
#endif
2134
2126
                        }
2135
2127
                        break;
2136
2128
                }
2137
2129
                case Ndis802_11StatusType_RadioState:
2138
 
                        radio_status = buf;
 
2130
                {
 
2131
                        struct ndis_radio_status_indication *radio_status = buf;
2139
2132
                        if (radio_status->radio_state ==
2140
2133
                            Ndis802_11RadioStatusOn)
2141
2134
                                INFO("radio is turned on");
2146
2139
                                 Ndis802_11RadioStatusSoftwareOff)
2147
2140
                                INFO("radio is turned off by software");
2148
2141
                        break;
 
2142
                }
2149
2143
#endif
2150
2144
                default:
2151
2145
                        /* is this RSSI indication? */
2165
2159
wstdcall void WIN_FUNC(NdisMIndicateStatusComplete,1)
2166
2160
        (struct ndis_mp_block *nmb)
2167
2161
{
2168
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2162
        struct ndis_device *wnd = nmb->wnd;
2169
2163
        ENTER2("%p", wnd);
2170
2164
        if (wnd->tx_ok)
2171
2165
                schedule_wrapndis_work(&wnd->tx_work);
2175
2169
wstdcall void NdisMSendComplete(struct ndis_mp_block *nmb,
2176
2170
                                struct ndis_packet *packet, NDIS_STATUS status)
2177
2171
{
2178
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2172
        struct ndis_device *wnd = nmb->wnd;
2179
2173
        ENTER4("%p, %08X", packet, status);
2180
2174
        assert_irql(_irql_ <= DISPATCH_LEVEL);
2181
2175
        if (deserialized_driver(wnd))
2211
2205
/* called via function pointer */
2212
2206
wstdcall void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb)
2213
2207
{
2214
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2208
        struct ndis_device *wnd = nmb->wnd;
2215
2209
        ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
2216
2210
        wnd->tx_ok = 1;
2217
2211
        schedule_wrapndis_work(&wnd->tx_work);
2220
2214
 
2221
2215
wstdcall void return_packet(void *arg1, void *arg2)
2222
2216
{
2223
 
        struct wrap_ndis_device *wnd;
 
2217
        struct ndis_device *wnd;
2224
2218
        struct ndis_packet *packet;
2225
2219
        struct miniport *mp;
2226
2220
        KIRQL irql;
2242
2236
                                         struct ndis_packet **packets,
2243
2237
                                         UINT nr_packets)
2244
2238
{
2245
 
        struct wrap_ndis_device *wnd;
 
2239
        struct ndis_device *wnd;
2246
2240
        ndis_buffer *buffer;
2247
2241
        struct ndis_packet *packet;
2248
2242
        struct sk_buff *skb;
2333
2327
                                   UINT packet_size)
2334
2328
{
2335
2329
        struct sk_buff *skb = NULL;
2336
 
        struct wrap_ndis_device *wnd;
 
2330
        struct ndis_device *wnd;
2337
2331
        unsigned int skb_size = 0;
2338
2332
        KIRQL irql;
2339
2333
        struct ndis_packet_oob_data *oob_data;
2450
2444
                                        struct ndis_packet *packet,
2451
2445
                                        NDIS_STATUS status, UINT bytes_txed)
2452
2446
{
2453
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2447
        struct ndis_device *wnd = nmb->wnd;
2454
2448
        struct sk_buff *skb;
2455
2449
        unsigned int skb_size;
2456
2450
        struct ndis_packet_oob_data *oob_data;
2515
2509
wstdcall void NdisMQueryInformationComplete(struct ndis_mp_block *nmb,
2516
2510
                                            NDIS_STATUS status)
2517
2511
{
2518
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2512
        struct ndis_device *wnd = nmb->wnd;
2519
2513
        typeof(wnd->ndis_req_task) task;
2520
2514
 
2521
2515
        ENTER2("nmb: %p, wnd: %p, %08X", nmb, wnd, status);
2532
2526
wstdcall void NdisMSetInformationComplete(struct ndis_mp_block *nmb,
2533
2527
                                          NDIS_STATUS status)
2534
2528
{
2535
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2529
        struct ndis_device *wnd = nmb->wnd;
2536
2530
        typeof(wnd->ndis_req_task) task;
2537
2531
 
2538
2532
        ENTER2("status = %08X", status);
2549
2543
wstdcall void NdisMResetComplete(struct ndis_mp_block *nmb,
2550
2544
                                 NDIS_STATUS status, BOOLEAN address_reset)
2551
2545
{
2552
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2546
        struct ndis_device *wnd = nmb->wnd;
2553
2547
        typeof(wnd->ndis_req_task) task;
2554
2548
 
2555
2549
        ENTER2("status: %08X, %u", status, address_reset);
2615
2609
wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3)
2616
2610
        (struct ndis_mp_block *nmb, BOOLEAN dma_size, ULONG max_phy_map)
2617
2611
{
2618
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2612
        struct ndis_device *wnd = nmb->wnd;
2619
2613
        ENTER2("dma_size=%d, maxtransfer=%u", dma_size, max_phy_map);
2620
2614
#ifdef CONFIG_X86_64
2621
2615
        if (dma_size != NDIS_DMA_64BITS) {
2638
2632
        (struct ndis_mp_block *nmb)
2639
2633
{
2640
2634
        ENTER3("");
2641
 
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
2642
2635
        return dma_get_cache_alignment();
2643
 
#else
2644
 
        return L1_CACHE_BYTES;
2645
 
#endif
2646
2636
}
2647
2637
 
2648
2638
wstdcall CHAR WIN_FUNC(NdisSystemProcessorCount,0)
2655
2645
        (ULONG *idle, ULONG *kernel_user, ULONG *index)
2656
2646
{
2657
2647
        int cpu = smp_processor_id();
2658
 
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)
2659
2648
        *idle = kstat_cpu(cpu).cpustat.idle;
2660
2649
        *kernel_user = kstat_cpu(cpu).cpustat.system +
2661
2650
                kstat_cpu(cpu).cpustat.user;
2662
 
#else
2663
 
        *idle = 0;
2664
 
        *kernel_user = 0;
2665
 
#endif
2666
2651
        *index = cpu;
2667
2652
}
2668
2653
 
2769
2754
wstdcall NDIS_STATUS WIN_FUNC(NdisMQueryAdapterInstanceName,2)
2770
2755
        (struct unicode_string *name, struct ndis_mp_block *nmb)
2771
2756
{
2772
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2757
        struct ndis_device *wnd = nmb->wnd;
2773
2758
        struct ansi_string ansi;
2774
2759
 
2775
2760
        if (wrap_is_pci_bus(wnd->wd->dev_bus))
2844
2829
        (NDIS_STATUS status, struct ndis_mp_block *nmb,
2845
2830
         struct ndis_request *ndis_request)
2846
2831
{
2847
 
        struct wrap_ndis_device *wnd = nmb->wnd;
 
2832
        struct ndis_device *wnd = nmb->wnd;
2848
2833
        typeof(wnd->ndis_req_task) task;
2849
2834
 
2850
2835
        ENTER3("%08X", status);
2909
2894
        TODO();
2910
2895
}
2911
2896
 
2912
 
#include "ndis_exports.h"
2913
 
 
2914
2897
static void *ndis_get_routine_address(char *name)
2915
2898
{
2916
2899
        int i;
2925
2908
}
2926
2909
 
2927
2910
/* ndis_init_device is called for each device */
2928
 
int ndis_init_device(struct wrap_ndis_device *wnd)
 
2911
int ndis_init_device(struct ndis_device *wnd)
2929
2912
{
2930
2913
        struct ndis_mp_block *nmb = wnd->nmb;
2931
2914
 
2955
2938
}
2956
2939
 
2957
2940
/* ndis_exit_device is called for each device */
2958
 
void ndis_exit_device(struct wrap_ndis_device *wnd)
 
2941
void ndis_exit_device(struct ndis_device *wnd)
2959
2942
{
2960
2943
        struct wrap_device_setting *setting;
2961
2944
        ENTER2("%p", wnd);