1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
30 * The purpose of rtl871x_io.c
33 * b. provides the protocol engine
34 * c. provides the software interface between caller and the hardware interface
36 * For r8712u, both sync/async operations are provided.
38 * Only sync read/write_mem operations are provided.
42 #define _RTL871X_IO_C_
44 #include "osdep_service.h"
45 #include "drv_types.h"
46 #include "rtl871x_io.h"
47 #include "osdep_intf.h"
50 static uint
_init_intf_hdl(struct _adapter
*padapter
,
51 struct intf_hdl
*pintf_hdl
)
53 struct intf_priv
*pintf_priv
;
54 void (*set_intf_option
)(u32
*poption
) = NULL
;
55 void (*set_intf_funs
)(struct intf_hdl
*pintf_hdl
);
56 void (*set_intf_ops
)(struct _io_ops
*pops
);
57 uint (*init_intf_priv
)(struct intf_priv
*pintfpriv
);
59 set_intf_option
= &(r8712_usb_set_intf_option
);
60 set_intf_funs
= &(r8712_usb_set_intf_funs
);
61 set_intf_ops
= &r8712_usb_set_intf_ops
;
62 init_intf_priv
= &r8712_usb_init_intf_priv
;
63 pintf_priv
= pintf_hdl
->pintfpriv
= (struct intf_priv
*)
64 _malloc(sizeof(struct intf_priv
));
65 if (pintf_priv
== NULL
)
66 goto _init_intf_hdl_fail
;
67 pintf_hdl
->adapter
= (u8
*)padapter
;
68 set_intf_option(&pintf_hdl
->intf_option
);
69 set_intf_funs(pintf_hdl
);
70 set_intf_ops(&pintf_hdl
->io_ops
);
71 pintf_priv
->intf_dev
= (u8
*)&(padapter
->dvobjpriv
);
72 if (init_intf_priv(pintf_priv
) == _FAIL
)
73 goto _init_intf_hdl_fail
;
77 kfree((u8
*)pintf_priv
);
81 static void _unload_intf_hdl(struct intf_priv
*pintfpriv
)
83 void (*unload_intf_priv
)(struct intf_priv
*pintfpriv
);
85 unload_intf_priv
= &r8712_usb_unload_intf_priv
;
86 unload_intf_priv(pintfpriv
);
88 kfree((u8
*)pintfpriv
);
91 static uint
register_intf_hdl(u8
*dev
, struct intf_hdl
*pintfhdl
)
93 struct _adapter
*adapter
= (struct _adapter
*)dev
;
95 pintfhdl
->intf_option
= 0;
96 pintfhdl
->adapter
= dev
;
97 pintfhdl
->intf_dev
= (u8
*)&(adapter
->dvobjpriv
);
98 if (_init_intf_hdl(adapter
, pintfhdl
) == false)
99 goto register_intf_hdl_fail
;
101 register_intf_hdl_fail
:
105 static void unregister_intf_hdl(struct intf_hdl
*pintfhdl
)
107 _unload_intf_hdl(pintfhdl
->pintfpriv
);
108 memset((u8
*)pintfhdl
, 0, sizeof(struct intf_hdl
));
111 uint
r8712_alloc_io_queue(struct _adapter
*adapter
)
114 struct io_queue
*pio_queue
;
115 struct io_req
*pio_req
;
117 pio_queue
= (struct io_queue
*)_malloc(sizeof(struct io_queue
));
118 if (pio_queue
== NULL
)
119 goto alloc_io_queue_fail
;
120 _init_listhead(&pio_queue
->free_ioreqs
);
121 _init_listhead(&pio_queue
->processing
);
122 _init_listhead(&pio_queue
->pending
);
123 spin_lock_init(&pio_queue
->lock
);
124 pio_queue
->pallocated_free_ioreqs_buf
= (u8
*)_malloc(NUM_IOREQ
*
125 (sizeof(struct io_req
)) + 4);
126 if ((pio_queue
->pallocated_free_ioreqs_buf
) == NULL
)
127 goto alloc_io_queue_fail
;
128 memset(pio_queue
->pallocated_free_ioreqs_buf
, 0,
129 (NUM_IOREQ
* (sizeof(struct io_req
)) + 4));
130 pio_queue
->free_ioreqs_buf
= pio_queue
->pallocated_free_ioreqs_buf
+ 4
131 - ((addr_t
)(pio_queue
->pallocated_free_ioreqs_buf
)
133 pio_req
= (struct io_req
*)(pio_queue
->free_ioreqs_buf
);
134 for (i
= 0; i
< NUM_IOREQ
; i
++) {
135 _init_listhead(&pio_req
->list
);
136 sema_init(&pio_req
->sema
, 0);
137 list_insert_tail(&pio_req
->list
, &pio_queue
->free_ioreqs
);
140 if ((register_intf_hdl((u8
*)adapter
, &(pio_queue
->intf
))) == _FAIL
)
141 goto alloc_io_queue_fail
;
142 adapter
->pio_queue
= pio_queue
;
146 kfree(pio_queue
->pallocated_free_ioreqs_buf
);
147 kfree((u8
*)pio_queue
);
149 adapter
->pio_queue
= NULL
;
153 void r8712_free_io_queue(struct _adapter
*adapter
)
155 struct io_queue
*pio_queue
= (struct io_queue
*)(adapter
->pio_queue
);
158 kfree(pio_queue
->pallocated_free_ioreqs_buf
);
159 adapter
->pio_queue
= NULL
;
160 unregister_intf_hdl(&pio_queue
->intf
);
161 kfree((u8
*)pio_queue
);