GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / uwb / i1480 / i1480u-wlp / netdev.c
blobfd0b0c5cf1d9b20b4e909262477d66b480bdce63
3 #include <linux/slab.h>
4 #include <linux/if_arp.h>
5 #include <linux/etherdevice.h>
7 #include "i1480u-wlp.h"
9 struct i1480u_cmd_set_ip_mas {
10 struct uwb_rccb rccb;
11 struct uwb_dev_addr addr;
12 u8 stream;
13 u8 owner;
14 u8 type; /* enum uwb_drp_type */
15 u8 baMAS[32];
16 } __attribute__((packed));
19 static
20 int i1480u_set_ip_mas(
21 struct uwb_rc *rc,
22 const struct uwb_dev_addr *dstaddr,
23 u8 stream, u8 owner, u8 type, unsigned long *mas)
26 int result;
27 struct i1480u_cmd_set_ip_mas *cmd;
28 struct uwb_rc_evt_confirm reply;
30 result = -ENOMEM;
31 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
32 if (cmd == NULL)
33 goto error_kzalloc;
34 cmd->rccb.bCommandType = 0xfd;
35 cmd->rccb.wCommand = cpu_to_le16(0x000e);
36 cmd->addr = *dstaddr;
37 cmd->stream = stream;
38 cmd->owner = owner;
39 cmd->type = type;
40 if (mas == NULL)
41 memset(cmd->baMAS, 0x00, sizeof(cmd->baMAS));
42 else
43 memcpy(cmd->baMAS, mas, sizeof(cmd->baMAS));
44 reply.rceb.bEventType = 0xfd;
45 reply.rceb.wEvent = cpu_to_le16(0x000e);
46 result = uwb_rc_cmd(rc, "SET-IP-MAS", &cmd->rccb, sizeof(*cmd),
47 &reply.rceb, sizeof(reply));
48 if (result < 0)
49 goto error_cmd;
50 if (reply.bResultCode != UWB_RC_RES_FAIL) {
51 dev_err(&rc->uwb_dev.dev,
52 "SET-IP-MAS: command execution failed: %d\n",
53 reply.bResultCode);
54 result = -EIO;
56 error_cmd:
57 kfree(cmd);
58 error_kzalloc:
59 return result;
63 * Inform a WLP interface of a MAS reservation
65 * @rc is assumed refcnted.
67 static int i1480u_mas_set_dev(struct uwb_dev *uwb_dev, struct uwb_rc *rc,
68 u8 stream, u8 owner, u8 type, unsigned long *mas)
70 int result = 0;
71 struct device *dev = &rc->uwb_dev.dev;
73 result = i1480u_set_ip_mas(rc, &uwb_dev->dev_addr, stream, owner,
74 type, mas);
75 if (result < 0) {
76 char rcaddrbuf[UWB_ADDR_STRSIZE], devaddrbuf[UWB_ADDR_STRSIZE];
77 uwb_dev_addr_print(rcaddrbuf, sizeof(rcaddrbuf),
78 &rc->uwb_dev.dev_addr);
79 uwb_dev_addr_print(devaddrbuf, sizeof(devaddrbuf),
80 &uwb_dev->dev_addr);
81 dev_err(dev, "Set IP MAS (%s to %s) failed: %d\n",
82 rcaddrbuf, devaddrbuf, result);
84 return result;
87 /**
88 * Called by bandwidth allocator when change occurs in reservation.
90 * @rsv: The reservation that is being established, modified, or
91 * terminated.
93 * When a reservation is established, modified, or terminated the upper layer
94 * (WLP here) needs set/update the currently available Media Access Slots
95 * that can be use for IP traffic.
97 * Our action taken during failure depends on how the reservation is being
98 * changed:
99 * - if reservation is being established we do nothing if we cannot set the
100 * new MAS to be used
101 * - if reservation is being terminated we revert back to PCA whether the
102 * SET IP MAS command succeeds or not.
104 void i1480u_bw_alloc_cb(struct uwb_rsv *rsv)
106 int result = 0;
107 struct i1480u *i1480u = rsv->pal_priv;
108 struct device *dev = &i1480u->usb_iface->dev;
109 struct uwb_dev *target_dev = rsv->target.dev;
110 struct uwb_rc *rc = i1480u->wlp.rc;
111 u8 stream = rsv->stream;
112 int type = rsv->type;
113 int is_owner = rsv->owner == &rc->uwb_dev;
114 unsigned long *bmp = rsv->mas.bm;
116 dev_err(dev, "WLP callback called - sending set ip mas\n");
117 /*user cannot change options while setting configuration*/
118 mutex_lock(&i1480u->options.mutex);
119 switch (rsv->state) {
120 case UWB_RSV_STATE_T_ACCEPTED:
121 case UWB_RSV_STATE_O_ESTABLISHED:
122 result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
123 type, bmp);
124 if (result < 0) {
125 dev_err(dev, "MAS reservation failed: %d\n", result);
126 goto out;
128 if (is_owner) {
129 wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
130 WLP_DRP | stream);
131 wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 0);
133 break;
134 case UWB_RSV_STATE_NONE:
135 /* revert back to PCA */
136 result = i1480u_mas_set_dev(target_dev, rc, stream, is_owner,
137 type, bmp);
138 if (result < 0)
139 dev_err(dev, "MAS reservation failed: %d\n", result);
140 /* Revert to PCA even though SET IP MAS failed. */
141 wlp_tx_hdr_set_delivery_id_type(&i1480u->options.def_tx_hdr,
142 i1480u->options.pca_base_priority);
143 wlp_tx_hdr_set_rts_cts(&i1480u->options.def_tx_hdr, 1);
144 break;
145 default:
146 dev_err(dev, "unexpected WLP reservation state: %s (%d).\n",
147 uwb_rsv_state_str(rsv->state), rsv->state);
148 break;
150 out:
151 mutex_unlock(&i1480u->options.mutex);
152 return;
157 * Called on 'ifconfig up'
159 int i1480u_open(struct net_device *net_dev)
161 int result;
162 struct i1480u *i1480u = netdev_priv(net_dev);
163 struct wlp *wlp = &i1480u->wlp;
164 struct uwb_rc *rc;
165 struct device *dev = &i1480u->usb_iface->dev;
167 rc = wlp->rc;
168 result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */
169 if (result < 0)
170 goto error_rx_setup;
172 result = uwb_radio_start(&wlp->pal);
173 if (result < 0)
174 goto error_radio_start;
176 netif_wake_queue(net_dev);
177 #ifdef i1480u_FLOW_CONTROL
178 result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);
179 if (result < 0) {
180 dev_err(dev, "Can't submit notification URB: %d\n", result);
181 goto error_notif_urb_submit;
183 #endif
184 /* Interface is up with an address, now we can create WSS */
185 result = wlp_wss_setup(net_dev, &wlp->wss);
186 if (result < 0) {
187 dev_err(dev, "Can't create WSS: %d. \n", result);
188 goto error_wss_setup;
190 return 0;
191 error_wss_setup:
192 #ifdef i1480u_FLOW_CONTROL
193 usb_kill_urb(i1480u->notif_urb);
194 error_notif_urb_submit:
195 #endif
196 uwb_radio_stop(&wlp->pal);
197 error_radio_start:
198 netif_stop_queue(net_dev);
199 i1480u_rx_release(i1480u);
200 error_rx_setup:
201 return result;
206 * Called on 'ifconfig down'
208 int i1480u_stop(struct net_device *net_dev)
210 struct i1480u *i1480u = netdev_priv(net_dev);
211 struct wlp *wlp = &i1480u->wlp;
213 BUG_ON(wlp->rc == NULL);
214 wlp_wss_remove(&wlp->wss);
215 netif_carrier_off(net_dev);
216 #ifdef i1480u_FLOW_CONTROL
217 usb_kill_urb(i1480u->notif_urb);
218 #endif
219 netif_stop_queue(net_dev);
220 uwb_radio_stop(&wlp->pal);
221 i1480u_rx_release(i1480u);
222 i1480u_tx_release(i1480u);
223 return 0;
228 * Change the interface config--we probably don't have to do anything.
230 int i1480u_set_config(struct net_device *net_dev, struct ifmap *map)
232 int result;
233 struct i1480u *i1480u = netdev_priv(net_dev);
234 BUG_ON(i1480u->wlp.rc == NULL);
235 result = 0;
236 return result;
240 * Change the MTU of the interface
242 int i1480u_change_mtu(struct net_device *net_dev, int mtu)
244 static union {
245 struct wlp_tx_hdr tx;
246 struct wlp_rx_hdr rx;
247 } i1480u_all_hdrs;
249 if (mtu < ETH_HLEN) /* We encap eth frames */
250 return -ERANGE;
251 if (mtu > 4000 - sizeof(i1480u_all_hdrs))
252 return -ERANGE;
253 net_dev->mtu = mtu;
254 return 0;
257 void i1480u_stop_queue(struct wlp *wlp)
259 struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
260 struct net_device *net_dev = i1480u->net_dev;
261 i1480u->tx_inflight.threshold = 0;
262 netif_stop_queue(net_dev);
265 void i1480u_start_queue(struct wlp *wlp)
267 struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
268 struct net_device *net_dev = i1480u->net_dev;
269 i1480u->tx_inflight.threshold = i1480u_TX_INFLIGHT_THRESHOLD;
270 netif_start_queue(net_dev);