Newer
Older
* If high byte of bcdDevice is nonzero, firmware is already
* downloaded. Don't try to do it again, or we'll hang the device.
*/
if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
info("Firmware present in device.");
info("Downloading firmware...");
kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
if ((result = kaweth_download_firmware(kaweth,
kaweth_new_code,
len_kaweth_new_code,
100,
2)) < 0) {
err("Error downloading firmware (%d)", result);
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
kaweth_new_code_fix,
len_kaweth_new_code_fix,
100,
3)) < 0) {
err("Error downloading firmware fix (%d)", result);
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
kaweth_trigger_code,
len_kaweth_trigger_code,
126,
2)) < 0) {
err("Error downloading trigger code (%d)", result);
goto err_fw;
}
if ((result = kaweth_download_firmware(kaweth,
kaweth_trigger_code_fix,
len_kaweth_trigger_code_fix,
126,
3)) < 0) {
err("Error downloading trigger code fix (%d)", result);
goto err_fw;
}
if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
err("Error triggering firmware (%d)", result);
goto err_fw;
}
/* Device will now disappear for a moment... */
info("Firmware loaded. I'll be back...");
err_fw:
free_page((unsigned long)kaweth->firmware_buf);
free_netdev(netdev);
return -EIO;
}
result = kaweth_read_configuration(kaweth);
if(result < 0) {
err("Error reading configuration (%d), no net device created", result);
info("Statistics collection: %x", kaweth->configuration.statistics_mask);
info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
(int)kaweth->configuration.hw_addr[0],
(int)kaweth->configuration.hw_addr[1],
(int)kaweth->configuration.hw_addr[2],
(int)kaweth->configuration.hw_addr[3],
(int)kaweth->configuration.hw_addr[4],
(int)kaweth->configuration.hw_addr[5]);
if(!memcmp(&kaweth->configuration.hw_addr,
&bcast_addr,
sizeof(bcast_addr))) {
err("Firmware not functioning properly, no net device created");
goto err_free_netdev;
}
if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
dbg("Error setting URB size");
goto err_free_netdev;
}
if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
err("Error setting SOFS wait");
goto err_free_netdev;
}
result = kaweth_set_receive_filter(kaweth,
KAWETH_PACKET_FILTER_DIRECTED |
KAWETH_PACKET_FILTER_BROADCAST |
KAWETH_PACKET_FILTER_MULTICAST);
if(result < 0) {
err("Error setting receive filter");
dbg("Initializing net device.");
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->tx_urb)
goto err_free_netdev;
kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->rx_urb)
goto err_only_tx;
kaweth->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->irq_urb)
goto err_tx_and_rx;
kaweth->intbuffer = usb_buffer_alloc( kaweth->dev,
INTBUFFERSIZE,
GFP_KERNEL,
&kaweth->intbufferhandle);
if (!kaweth->intbuffer)
goto err_tx_and_rx_and_irq;
kaweth->rx_buf = usb_buffer_alloc( kaweth->dev,
KAWETH_BUF_SIZE,
GFP_KERNEL,
&kaweth->rxbufferhandle);
if (!kaweth->rx_buf)
goto err_all_but_rxbuf;
memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr));
memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr,
sizeof(kaweth->configuration.hw_addr));
netdev->open = kaweth_open;
netdev->stop = kaweth_close;
netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
netdev->tx_timeout = kaweth_tx_timeout;
netdev->hard_start_xmit = kaweth_start_xmit;
netdev->set_multicast_list = kaweth_set_rx_mode;
netdev->get_stats = kaweth_netdev_stats;
netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
SET_ETHTOOL_OPS(netdev, &ops);
/* kaweth is zeroed as part of alloc_netdev */
INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
usb_set_intfdata(intf, kaweth);
#if 0
// dma_supported() is deeply broken on almost all architectures
if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
kaweth->net->features |= NETIF_F_HIGHDMA;
#endif
SET_NETDEV_DEV(netdev, &intf->dev);
if (register_netdev(netdev) != 0) {
err("Error registering netdev.");
info("kaweth interface created at %s", kaweth->net->name);
dbg("Kaweth probe returning.");
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
return 0;
err_intfdata:
usb_set_intfdata(intf, NULL);
usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
err_all_but_rxbuf:
usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
err_tx_and_rx_and_irq:
usb_free_urb(kaweth->irq_urb);
err_tx_and_rx:
usb_free_urb(kaweth->rx_urb);
err_only_tx:
usb_free_urb(kaweth->tx_urb);
err_free_netdev:
free_netdev(netdev);
return -EIO;
}
/****************************************************************
* kaweth_disconnect
****************************************************************/
static void kaweth_disconnect(struct usb_interface *intf)
{
struct kaweth_device *kaweth = usb_get_intfdata(intf);
struct net_device *netdev;
usb_set_intfdata(intf, NULL);
if (!kaweth) {
warn("unregistering non-existant device");
dbg("Unregistering net device");
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
unregister_netdev(netdev);
usb_free_urb(kaweth->rx_urb);
usb_free_urb(kaweth->tx_urb);
usb_free_urb(kaweth->irq_urb);
usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
free_netdev(netdev);
}
// FIXME this completion stuff is a modified clone of
// an OLD version of some stuff in usb.c ...
struct usb_api_data {
wait_queue_head_t wqh;
int done;
};
/*-------------------------------------------------------------------*
* completion handler for compatibility wrappers (sync control/bulk) *
*-------------------------------------------------------------------*/
static void usb_api_blocking_completion(struct urb *urb)
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
{
struct usb_api_data *awd = (struct usb_api_data *)urb->context;
awd->done=1;
wake_up(&awd->wqh);
}
/*-------------------------------------------------------------------*
* COMPATIBILITY STUFF *
*-------------------------------------------------------------------*/
// Starts urb and waits for completion or timeout
static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
{
struct usb_api_data awd;
int status;
init_waitqueue_head(&awd.wqh);
awd.done = 0;
urb->context = &awd;
status = usb_submit_urb(urb, GFP_NOIO);
if (status) {
// something went wrong
usb_free_urb(urb);
return status;
}
if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
// timeout
warn("usb_control/bulk_msg: timeout");
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
usb_kill_urb(urb); // remove urb safely
status = -ETIMEDOUT;
}
else {
status = urb->status;
}
if (actual_length) {
*actual_length = urb->actual_length;
}
usb_free_urb(urb);
return status;
}
/*-------------------------------------------------------------------*/
// returns status (negative) or length (positive)
static int kaweth_internal_control_msg(struct usb_device *usb_dev,
unsigned int pipe,
struct usb_ctrlrequest *cmd, void *data,
int len, int timeout)
{
struct urb *urb;
int retv;
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data,
len, usb_api_blocking_completion, NULL);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0) {
return retv;
}
else {
return length;
}
}
/****************************************************************
* kaweth_init
****************************************************************/
static int __init kaweth_init(void)
{
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
return usb_register(&kaweth_driver);
}
/****************************************************************
* kaweth_exit
****************************************************************/
static void __exit kaweth_exit(void)
{
usb_deregister(&kaweth_driver);
}
module_init(kaweth_init);
module_exit(kaweth_exit);