upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / uwb / i1480 / i1480u-wlp / netdev.c
1 /*
2  * WUSB Wire Adapter: WLP interface
3  * Driver for the Linux Network stack.
4  *
5  * Copyright (C) 2005-2006 Intel Corporation
6  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *
22  *
23  * FIXME: docs
24  *
25  * Implementation of the netdevice linkage (except tx and rx related stuff).
26  *
27  * ROADMAP:
28  *
29  *   ENTRY POINTS (Net device):
30  *
31  *     i1480u_open(): Called when we ifconfig up the interface;
32  *                    associates to a UWB host controller, reserves
33  *                    bandwidth (MAS), sets up RX USB URB and starts
34  *                    the queue.
35  *
36  *     i1480u_stop(): Called when we ifconfig down a interface;
37  *                    reverses _open().
38  *
39  *     i1480u_set_config():
40  */
41
42 #include <linux/slab.h>
43 #include <linux/if_arp.h>
44 #include <linux/etherdevice.h>
45
46 #include "i1480u-wlp.h"
47
48 struct i1480u_cmd_set_ip_mas {
49         struct uwb_rccb     rccb;
50         struct uwb_dev_addr addr;
51         u8                  stream;
52         u8                  owner;
53         u8                  type;       /* enum uwb_drp_type */
54         u8                  baMAS[32];
55 } __attribute__((packed));
56
57
58 static
59 int i1480u_set_ip_mas(
60         struct uwb_rc *rc,
61         const struct uwb_dev_addr *dstaddr,
62         u8 stream, u8 owner, u8 type, unsigned long *mas)
63 {
64
65         int result;
66         struct i1480u_cmd_set_ip_mas *cmd;
67         struct uwb_rc_evt_confirm reply;
68
69         result = -ENOMEM;
70         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
71         if (cmd == NULL)
72                 goto error_kzalloc;
73         cmd->rccb.bCommandType = 0xfd;
74         cmd->rccb.wCommand = cpu_to_le16(0x000e);
75         cmd->addr = *dstaddr;
76         cmd->stream = stream;
77         cmd->owner = owner;
78         cmd->type = type;
79         if (mas == NULL)
80                 memset(cmd->baMAS, 0x00, sizeof(cmd->baMAS));
81         else
82                 memcpy(cmd->baMAS, mas, sizeof(cmd->baMAS));
83         reply.rceb.bEventType = 0xfd;
84         reply.rceb.wEvent = cpu_to_le16(0x000e);
85         result = uwb_rc_cmd(rc, "SET-IP-MAS", &cmd->rccb, sizeof(*cmd),
86                             &reply.rceb, sizeof(reply));
87         if (result < 0)
88                 goto error_cmd;
89         if (reply.bResultCode != UWB_RC_RES_FAIL) {
90                 dev_err(&rc->uwb_dev.dev,
91                         "SET-IP-MAS: command execution failed: %d\n",
92                         reply.bResultCode);
93                 result = -EIO;
94         }
95 error_cmd:
96         kfree(cmd);
97 error_kzalloc:
98         return result;
99 }
100
101 /*
102  * Inform a WLP interface of a MAS reservation
103  *
104  * @rc is assumed refcnted.
105  */
106 /* FIXME: detect if remote device is WLP capable? */
107 static int i1480u_mas_set_dev(struct uwb_dev *uwb_dev, struct uwb_rc *rc,
108                               u8 stream, u8 owner, u8 type, unsigned long *mas)
109 {
110         int result = 0;
111         struct device *dev = &rc->uwb_dev.dev;
112
113         result = i1480u_set_ip_mas(rc, &uwb_dev->dev_addr, stream, owner,
114                                    type, mas);
115         if (result < 0) {
116                 char rcaddrbuf[UWB_ADDR_STRSIZE], devaddrbuf[UWB_ADDR_STRSIZE];
117                 uwb_dev_addr_print(rcaddrbuf, sizeof(rcaddrbuf),
118                                    &rc->uwb_dev.dev_addr);
119                 uwb_dev_addr_print(devaddrbuf, sizeof(devaddrbuf),
120                                    &uwb_dev->dev_addr);
121                 dev_err(dev, "Set IP MAS (%s to %s) failed: %d\n",
122                         rcaddrbuf, devaddrbuf, result);
123         }
124         return result;
125 }
126
127 /**
128  * Called by bandwidth allocator when change occurs in reservation.
129  *
130  * @rsv:     The reservation that is being established, modified, or
131  *           terminated.
132  *
133  * When a reservation is established, modified, or terminated the upper layer
134  * (WLP here) needs set/update the currently available Media Access Slots
135  * that can be use for IP traffic.
136  *
137  * Our action taken during failure depends on how the reservation is being
138  * changed:
139  * - if reservation is being established we do nothing if we cannot set the
140  *   new MAS to be used
141  * - if reservation is being terminated we revert back to PCA whether the
142  *   SET IP MAS command succeeds or not.
143  */
144 void i1480u_bw_alloc_cb(struct uwb_rsv *rsv)
145 {
146         int result = 0;
147         struct i1480u *i1480u = rsv->pal_priv;
148         struct device *dev = &i1480u->usb_iface->dev;
149         struct uwb_dev *target_dev = rsv->target.dev;
150         struct uwb_rc *rc = i1480u->wlp.rc;
151         u8 stream = rsv->stream;
152         int type = rsv->type;
153         int is_owner = rsv->owner == &rc->uwb_dev;
154         unsigned long *bmp = rsv->mas.bm;
155
156         dev_err(dev, "WLP callback called - sending set ip mas\n");
157         /*user cannot change options while setting configuration*/
158         mutex_lock(&i1480u->options.mutex);
159         switch (rsv->state) {
160         case UWB_RSV_STATE_T_ACCEPTED:
161         case UWB_RSV_STATE_O_ESTABLISHED:
162                 result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
163                                         type, bmp);
164                 if (result < 0) {
165                         dev_err(dev, "MAS reservation failed: %d\n", result);
166                         goto out;
167                 }
168                 if (is_owner) {
169                         wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
170                                                         WLP_DRP | stream);
171                         wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 0);
172                 }
173                 break;
174         case UWB_RSV_STATE_NONE:
175                 /* revert back to PCA */
176                 result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
177                                             type, bmp);
178                 if (result < 0)
179                         dev_err(dev, "MAS reservation failed: %d\n", result);
180                 /* Revert to PCA even though SET IP MAS failed. */
181                 wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
182                                                 i1480u->options.pca_base_priority);
183                 wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 1);
184                 break;
185         default:
186                 dev_err(dev, "unexpected WLP reservation state: %s (%d).\n",
187                         uwb_rsv_state_str(rsv->state), rsv->state);
188                 break;
189         }
190 out:
191         mutex_unlock(&i1480u->options.mutex);
192         return;
193 }
194
195 /**
196  *
197  * Called on 'ifconfig up'
198  */
199 int i1480u_open(struct net_device *net_dev)
200 {
201         int result;
202         struct i1480u *i1480u = netdev_priv(net_dev);
203         struct wlp *wlp = &i1480u->wlp;
204         struct uwb_rc *rc;
205         struct device *dev = &i1480u->usb_iface->dev;
206
207         rc = wlp->rc;
208         result = i1480u_rx_setup(i1480u);               /* Alloc RX stuff */
209         if (result < 0)
210                 goto error_rx_setup;
211
212         result = uwb_radio_start(&wlp->pal);
213         if (result < 0)
214                 goto error_radio_start;
215
216         netif_wake_queue(net_dev);
217 #ifdef i1480u_FLOW_CONTROL
218         result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);
219         if (result < 0) {
220                 dev_err(dev, "Can't submit notification URB: %d\n", result);
221                 goto error_notif_urb_submit;
222         }
223 #endif
224         /* Interface is up with an address, now we can create WSS */
225         result = wlp_wss_setup(net_dev, &wlp->wss);
226         if (result < 0) {
227                 dev_err(dev, "Can't create WSS: %d. \n", result);
228                 goto error_wss_setup;
229         }
230         return 0;
231 error_wss_setup:
232 #ifdef i1480u_FLOW_CONTROL
233         usb_kill_urb(i1480u->notif_urb);
234 error_notif_urb_submit:
235 #endif
236         uwb_radio_stop(&wlp->pal);
237 error_radio_start:
238         netif_stop_queue(net_dev);
239         i1480u_rx_release(i1480u);
240 error_rx_setup:
241         return result;
242 }
243
244
245 /**
246  * Called on 'ifconfig down'
247  */
248 int i1480u_stop(struct net_device *net_dev)
249 {
250         struct i1480u *i1480u = netdev_priv(net_dev);
251         struct wlp *wlp = &i1480u->wlp;
252
253         BUG_ON(wlp->rc == NULL);
254         wlp_wss_remove(&wlp->wss);
255         netif_carrier_off(net_dev);
256 #ifdef i1480u_FLOW_CONTROL
257         usb_kill_urb(i1480u->notif_urb);
258 #endif
259         netif_stop_queue(net_dev);
260         uwb_radio_stop(&wlp->pal);
261         i1480u_rx_release(i1480u);
262         i1480u_tx_release(i1480u);
263         return 0;
264 }
265
266 /**
267  *
268  * Change the interface config--we probably don't have to do anything.
269  */
270 int i1480u_set_config(struct net_device *net_dev, struct ifmap *map)
271 {
272         int result;
273         struct i1480u *i1480u = netdev_priv(net_dev);
274         BUG_ON(i1480u->wlp.rc == NULL);
275         result = 0;
276         return result;
277 }
278
279 /**
280  * Change the MTU of the interface
281  */
282 int i1480u_change_mtu(struct net_device *net_dev, int mtu)
283 {
284         static union {
285                 struct wlp_tx_hdr tx;
286                 struct wlp_rx_hdr rx;
287         } i1480u_all_hdrs;
288
289         if (mtu < ETH_HLEN)     /* We encap eth frames */
290                 return -ERANGE;
291         if (mtu > 4000 - sizeof(i1480u_all_hdrs))
292                 return -ERANGE;
293         net_dev->mtu = mtu;
294         return 0;
295 }
296
297 /**
298  * Stop the network queue
299  *
300  * Enable WLP substack to stop network queue. We also set the flow control
301  * threshold at this time to prevent the flow control from restarting the
302  * queue.
303  *
304  * we are loosing the current threshold value here ... FIXME?
305  */
306 void i1480u_stop_queue(struct wlp *wlp)
307 {
308         struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
309         struct net_device *net_dev = i1480u->net_dev;
310         i1480u->tx_inflight.threshold = 0;
311         netif_stop_queue(net_dev);
312 }
313
314 /**
315  * Start the network queue
316  *
317  * Enable WLP substack to start network queue. Also re-enable the flow
318  * control to manage the queue again.
319  *
320  * We re-enable the flow control by storing the default threshold in the
321  * flow control threshold. This means that if the user modified the
322  * threshold before the queue was stopped and restarted that information
323  * will be lost. FIXME?
324  */
325 void i1480u_start_queue(struct wlp *wlp)
326 {
327         struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
328         struct net_device *net_dev = i1480u->net_dev;
329         i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
330         netif_start_queue(net_dev);
331 }