diff options
Diffstat (limited to 'drivers/net')
58 files changed, 1562 insertions, 1208 deletions
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 59c33925be62..b936373ab2a5 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
| @@ -225,6 +225,7 @@ static struct eisa_device_id el3_eisa_ids[] = { | |||
| 225 | { "TCM5095" }, | 225 | { "TCM5095" }, |
| 226 | { "" } | 226 | { "" } |
| 227 | }; | 227 | }; |
| 228 | MODULE_DEVICE_TABLE(eisa, el3_eisa_ids); | ||
| 228 | 229 | ||
| 229 | static int el3_eisa_probe (struct device *device); | 230 | static int el3_eisa_probe (struct device *device); |
| 230 | 231 | ||
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index af301f09d674..df42e28cc80f 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
| @@ -851,6 +851,7 @@ static struct eisa_device_id vortex_eisa_ids[] = { | |||
| 851 | { "TCM5970", CH_3C597 }, | 851 | { "TCM5970", CH_3C597 }, |
| 852 | { "" } | 852 | { "" } |
| 853 | }; | 853 | }; |
| 854 | MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); | ||
| 854 | 855 | ||
| 855 | static int vortex_eisa_probe(struct device *device); | 856 | static int vortex_eisa_probe(struct device *device); |
| 856 | static int vortex_eisa_remove(struct device *device); | 857 | static int vortex_eisa_remove(struct device *device); |
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index a075246f6f43..71a4f60f7325 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c | |||
| @@ -163,11 +163,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); | |||
| 163 | #define SET_NETDEV_DEV(net, pdev) do{} while(0) | 163 | #define SET_NETDEV_DEV(net, pdev) do{} while(0) |
| 164 | #endif | 164 | #endif |
| 165 | 165 | ||
| 166 | #if LINUX_VERSION_CODE >= 0x2051c | ||
| 167 | #define ace_sync_irq(irq) synchronize_irq(irq) | 166 | #define ace_sync_irq(irq) synchronize_irq(irq) |
| 168 | #else | ||
| 169 | #define ace_sync_irq(irq) synchronize_irq() | ||
| 170 | #endif | ||
| 171 | 167 | ||
| 172 | #ifndef offset_in_page | 168 | #ifndef offset_in_page |
| 173 | #define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK) | 169 | #define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK) |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6a407070c2e8..3fb354d9c515 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -85,6 +85,7 @@ | |||
| 85 | #define AD_LINK_SPEED_BITMASK_10MBPS 0x2 | 85 | #define AD_LINK_SPEED_BITMASK_10MBPS 0x2 |
| 86 | #define AD_LINK_SPEED_BITMASK_100MBPS 0x4 | 86 | #define AD_LINK_SPEED_BITMASK_100MBPS 0x4 |
| 87 | #define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 | 87 | #define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 |
| 88 | #define AD_LINK_SPEED_BITMASK_10000MBPS 0x10 | ||
| 88 | //endalloun | 89 | //endalloun |
| 89 | 90 | ||
| 90 | // compare MAC addresses | 91 | // compare MAC addresses |
| @@ -99,7 +100,7 @@ static u16 __get_link_speed(struct port *port); | |||
| 99 | static u8 __get_duplex(struct port *port); | 100 | static u8 __get_duplex(struct port *port); |
| 100 | static inline void __initialize_port_locks(struct port *port); | 101 | static inline void __initialize_port_locks(struct port *port); |
| 101 | //conversions | 102 | //conversions |
| 102 | static void __ntohs_lacpdu(struct lacpdu *lacpdu); | 103 | static void __htons_lacpdu(struct lacpdu *lacpdu); |
| 103 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); | 104 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); |
| 104 | 105 | ||
| 105 | 106 | ||
| @@ -330,7 +331,8 @@ static inline void __release_rx_machine_lock(struct port *port) | |||
| 330 | * 0, | 331 | * 0, |
| 331 | * %AD_LINK_SPEED_BITMASK_10MBPS, | 332 | * %AD_LINK_SPEED_BITMASK_10MBPS, |
| 332 | * %AD_LINK_SPEED_BITMASK_100MBPS, | 333 | * %AD_LINK_SPEED_BITMASK_100MBPS, |
| 333 | * %AD_LINK_SPEED_BITMASK_1000MBPS | 334 | * %AD_LINK_SPEED_BITMASK_1000MBPS, |
| 335 | * %AD_LINK_SPEED_BITMASK_10000MBPS | ||
| 334 | */ | 336 | */ |
| 335 | static u16 __get_link_speed(struct port *port) | 337 | static u16 __get_link_speed(struct port *port) |
| 336 | { | 338 | { |
| @@ -357,6 +359,10 @@ static u16 __get_link_speed(struct port *port) | |||
| 357 | speed = AD_LINK_SPEED_BITMASK_1000MBPS; | 359 | speed = AD_LINK_SPEED_BITMASK_1000MBPS; |
| 358 | break; | 360 | break; |
| 359 | 361 | ||
| 362 | case SPEED_10000: | ||
| 363 | speed = AD_LINK_SPEED_BITMASK_10000MBPS; | ||
| 364 | break; | ||
| 365 | |||
| 360 | default: | 366 | default: |
| 361 | speed = 0; // unknown speed value from ethtool. shouldn't happen | 367 | speed = 0; // unknown speed value from ethtool. shouldn't happen |
| 362 | break; | 368 | break; |
| @@ -414,23 +420,23 @@ static inline void __initialize_port_locks(struct port *port) | |||
| 414 | 420 | ||
| 415 | //conversions | 421 | //conversions |
| 416 | /** | 422 | /** |
| 417 | * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order | 423 | * __htons_lacpdu - convert the contents of a LACPDU to network byte order |
| 418 | * @lacpdu: the speicifed lacpdu | 424 | * @lacpdu: the speicifed lacpdu |
| 419 | * | 425 | * |
| 420 | * For each multi-byte field in the lacpdu, convert its content | 426 | * For each multi-byte field in the lacpdu, convert its content |
| 421 | */ | 427 | */ |
| 422 | static void __ntohs_lacpdu(struct lacpdu *lacpdu) | 428 | static void __htons_lacpdu(struct lacpdu *lacpdu) |
| 423 | { | 429 | { |
| 424 | if (lacpdu) { | 430 | if (lacpdu) { |
| 425 | lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority); | 431 | lacpdu->actor_system_priority = htons(lacpdu->actor_system_priority); |
| 426 | lacpdu->actor_key = ntohs(lacpdu->actor_key); | 432 | lacpdu->actor_key = htons(lacpdu->actor_key); |
| 427 | lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority); | 433 | lacpdu->actor_port_priority = htons(lacpdu->actor_port_priority); |
| 428 | lacpdu->actor_port = ntohs(lacpdu->actor_port); | 434 | lacpdu->actor_port = htons(lacpdu->actor_port); |
| 429 | lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority); | 435 | lacpdu->partner_system_priority = htons(lacpdu->partner_system_priority); |
| 430 | lacpdu->partner_key = ntohs(lacpdu->partner_key); | 436 | lacpdu->partner_key = htons(lacpdu->partner_key); |
| 431 | lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority); | 437 | lacpdu->partner_port_priority = htons(lacpdu->partner_port_priority); |
| 432 | lacpdu->partner_port = ntohs(lacpdu->partner_port); | 438 | lacpdu->partner_port = htons(lacpdu->partner_port); |
| 433 | lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay); | 439 | lacpdu->collector_max_delay = htons(lacpdu->collector_max_delay); |
| 434 | } | 440 | } |
| 435 | } | 441 | } |
| 436 | 442 | ||
| @@ -490,11 +496,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) | |||
| 490 | // validate lacpdu and port | 496 | // validate lacpdu and port |
| 491 | if (lacpdu && port) { | 497 | if (lacpdu && port) { |
| 492 | // record the new parameter values for the partner operational | 498 | // record the new parameter values for the partner operational |
| 493 | port->partner_oper_port_number = lacpdu->actor_port; | 499 | port->partner_oper_port_number = ntohs(lacpdu->actor_port); |
| 494 | port->partner_oper_port_priority = lacpdu->actor_port_priority; | 500 | port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority); |
| 495 | port->partner_oper_system = lacpdu->actor_system; | 501 | port->partner_oper_system = lacpdu->actor_system; |
| 496 | port->partner_oper_system_priority = lacpdu->actor_system_priority; | 502 | port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority); |
| 497 | port->partner_oper_key = lacpdu->actor_key; | 503 | port->partner_oper_key = ntohs(lacpdu->actor_key); |
| 498 | // zero partener's lase states | 504 | // zero partener's lase states |
| 499 | port->partner_oper_port_state = 0; | 505 | port->partner_oper_port_state = 0; |
| 500 | port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); | 506 | port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); |
| @@ -561,11 +567,11 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port) | |||
| 561 | // validate lacpdu and port | 567 | // validate lacpdu and port |
| 562 | if (lacpdu && port) { | 568 | if (lacpdu && port) { |
| 563 | // check if any parameter is different | 569 | // check if any parameter is different |
| 564 | if ((lacpdu->actor_port != port->partner_oper_port_number) || | 570 | if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) || |
| 565 | (lacpdu->actor_port_priority != port->partner_oper_port_priority) || | 571 | (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) || |
| 566 | MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || | 572 | MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || |
| 567 | (lacpdu->actor_system_priority != port->partner_oper_system_priority) || | 573 | (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) || |
| 568 | (lacpdu->actor_key != port->partner_oper_key) || | 574 | (ntohs(lacpdu->actor_key) != port->partner_oper_key) || |
| 569 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) | 575 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) |
| 570 | ) { | 576 | ) { |
| 571 | // update the state machine Selected variable | 577 | // update the state machine Selected variable |
| @@ -628,11 +634,11 @@ static void __choose_matched(struct lacpdu *lacpdu, struct port *port) | |||
| 628 | // validate lacpdu and port | 634 | // validate lacpdu and port |
| 629 | if (lacpdu && port) { | 635 | if (lacpdu && port) { |
| 630 | // check if all parameters are alike | 636 | // check if all parameters are alike |
| 631 | if (((lacpdu->partner_port == port->actor_port_number) && | 637 | if (((ntohs(lacpdu->partner_port) == port->actor_port_number) && |
| 632 | (lacpdu->partner_port_priority == port->actor_port_priority) && | 638 | (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) && |
| 633 | !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && | 639 | !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && |
| 634 | (lacpdu->partner_system_priority == port->actor_system_priority) && | 640 | (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) && |
| 635 | (lacpdu->partner_key == port->actor_oper_port_key) && | 641 | (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) && |
| 636 | ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || | 642 | ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || |
| 637 | // or this is individual link(aggregation == FALSE) | 643 | // or this is individual link(aggregation == FALSE) |
| 638 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) | 644 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) |
| @@ -662,11 +668,11 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) | |||
| 662 | // validate lacpdu and port | 668 | // validate lacpdu and port |
| 663 | if (lacpdu && port) { | 669 | if (lacpdu && port) { |
| 664 | // check if any parameter is different | 670 | // check if any parameter is different |
| 665 | if ((lacpdu->partner_port != port->actor_port_number) || | 671 | if ((ntohs(lacpdu->partner_port) != port->actor_port_number) || |
| 666 | (lacpdu->partner_port_priority != port->actor_port_priority) || | 672 | (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) || |
| 667 | MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || | 673 | MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || |
| 668 | (lacpdu->partner_system_priority != port->actor_system_priority) || | 674 | (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) || |
| 669 | (lacpdu->partner_key != port->actor_oper_port_key) || | 675 | (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) || |
| 670 | ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || | 676 | ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || |
| 671 | ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || | 677 | ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || |
| 672 | ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || | 678 | ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || |
| @@ -775,6 +781,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) | |||
| 775 | case AD_LINK_SPEED_BITMASK_1000MBPS: | 781 | case AD_LINK_SPEED_BITMASK_1000MBPS: |
| 776 | bandwidth = aggregator->num_of_ports * 1000; | 782 | bandwidth = aggregator->num_of_ports * 1000; |
| 777 | break; | 783 | break; |
| 784 | case AD_LINK_SPEED_BITMASK_10000MBPS: | ||
| 785 | bandwidth = aggregator->num_of_ports * 10000; | ||
| 786 | break; | ||
| 778 | default: | 787 | default: |
| 779 | bandwidth=0; // to silent the compilor .... | 788 | bandwidth=0; // to silent the compilor .... |
| 780 | } | 789 | } |
| @@ -847,7 +856,7 @@ static inline void __update_lacpdu_from_port(struct port *port) | |||
| 847 | */ | 856 | */ |
| 848 | 857 | ||
| 849 | /* Convert all non u8 parameters to Big Endian for transmit */ | 858 | /* Convert all non u8 parameters to Big Endian for transmit */ |
| 850 | __ntohs_lacpdu(lacpdu); | 859 | __htons_lacpdu(lacpdu); |
| 851 | } | 860 | } |
| 852 | 861 | ||
| 853 | ////////////////////////////////////////////////////////////////////////////////////// | 862 | ////////////////////////////////////////////////////////////////////////////////////// |
| @@ -2171,7 +2180,6 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u | |||
| 2171 | 2180 | ||
| 2172 | switch (lacpdu->subtype) { | 2181 | switch (lacpdu->subtype) { |
| 2173 | case AD_TYPE_LACPDU: | 2182 | case AD_TYPE_LACPDU: |
| 2174 | __ntohs_lacpdu(lacpdu); | ||
| 2175 | dprintk("Received LACPDU on port %d\n", port->actor_port_number); | 2183 | dprintk("Received LACPDU on port %d\n", port->actor_port_number); |
| 2176 | ad_rx_machine(lacpdu, port); | 2184 | ad_rx_machine(lacpdu, port); |
| 2177 | break; | 2185 | break; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 850aae21a2fe..0fb5f653d3ce 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -96,6 +96,7 @@ static char *lacp_rate = NULL; | |||
| 96 | static char *xmit_hash_policy = NULL; | 96 | static char *xmit_hash_policy = NULL; |
| 97 | static int arp_interval = BOND_LINK_ARP_INTERV; | 97 | static int arp_interval = BOND_LINK_ARP_INTERV; |
| 98 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 98 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
| 99 | static char *arp_validate = NULL; | ||
| 99 | struct bond_params bonding_defaults; | 100 | struct bond_params bonding_defaults; |
| 100 | 101 | ||
| 101 | module_param(max_bonds, int, 0); | 102 | module_param(max_bonds, int, 0); |
| @@ -127,6 +128,8 @@ module_param(arp_interval, int, 0); | |||
| 127 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); | 128 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); |
| 128 | module_param_array(arp_ip_target, charp, NULL, 0); | 129 | module_param_array(arp_ip_target, charp, NULL, 0); |
| 129 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); | 130 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); |
| 131 | module_param(arp_validate, charp, 0); | ||
| 132 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | ||
| 130 | 133 | ||
| 131 | /*----------------------------- Global variables ----------------------------*/ | 134 | /*----------------------------- Global variables ----------------------------*/ |
| 132 | 135 | ||
| @@ -170,6 +173,14 @@ struct bond_parm_tbl xmit_hashtype_tbl[] = { | |||
| 170 | { NULL, -1}, | 173 | { NULL, -1}, |
| 171 | }; | 174 | }; |
| 172 | 175 | ||
| 176 | struct bond_parm_tbl arp_validate_tbl[] = { | ||
| 177 | { "none", BOND_ARP_VALIDATE_NONE}, | ||
| 178 | { "active", BOND_ARP_VALIDATE_ACTIVE}, | ||
| 179 | { "backup", BOND_ARP_VALIDATE_BACKUP}, | ||
| 180 | { "all", BOND_ARP_VALIDATE_ALL}, | ||
| 181 | { NULL, -1}, | ||
| 182 | }; | ||
| 183 | |||
| 173 | /*-------------------------- Forward declarations ---------------------------*/ | 184 | /*-------------------------- Forward declarations ---------------------------*/ |
| 174 | 185 | ||
| 175 | static void bond_send_gratuitous_arp(struct bonding *bond); | 186 | static void bond_send_gratuitous_arp(struct bonding *bond); |
| @@ -638,6 +649,7 @@ verify: | |||
| 638 | case SPEED_10: | 649 | case SPEED_10: |
| 639 | case SPEED_100: | 650 | case SPEED_100: |
| 640 | case SPEED_1000: | 651 | case SPEED_1000: |
| 652 | case SPEED_10000: | ||
| 641 | break; | 653 | break; |
| 642 | default: | 654 | default: |
| 643 | return -1; | 655 | return -1; |
| @@ -1210,10 +1222,14 @@ static int bond_compute_features(struct bonding *bond) | |||
| 1210 | unsigned long features = BOND_INTERSECT_FEATURES; | 1222 | unsigned long features = BOND_INTERSECT_FEATURES; |
| 1211 | struct slave *slave; | 1223 | struct slave *slave; |
| 1212 | struct net_device *bond_dev = bond->dev; | 1224 | struct net_device *bond_dev = bond->dev; |
| 1225 | unsigned short max_hard_header_len = ETH_HLEN; | ||
| 1213 | int i; | 1226 | int i; |
| 1214 | 1227 | ||
| 1215 | bond_for_each_slave(bond, slave, i) | 1228 | bond_for_each_slave(bond, slave, i) { |
| 1216 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); | 1229 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); |
| 1230 | if (slave->dev->hard_header_len > max_hard_header_len) | ||
| 1231 | max_hard_header_len = slave->dev->hard_header_len; | ||
| 1232 | } | ||
| 1217 | 1233 | ||
| 1218 | if ((features & NETIF_F_SG) && | 1234 | if ((features & NETIF_F_SG) && |
| 1219 | !(features & NETIF_F_ALL_CSUM)) | 1235 | !(features & NETIF_F_ALL_CSUM)) |
| @@ -1231,6 +1247,7 @@ static int bond_compute_features(struct bonding *bond) | |||
| 1231 | 1247 | ||
| 1232 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | 1248 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); |
| 1233 | bond_dev->features = features; | 1249 | bond_dev->features = features; |
| 1250 | bond_dev->hard_header_len = max_hard_header_len; | ||
| 1234 | 1251 | ||
| 1235 | return 0; | 1252 | return 0; |
| 1236 | } | 1253 | } |
| @@ -1365,6 +1382,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1365 | } | 1382 | } |
| 1366 | 1383 | ||
| 1367 | new_slave->dev = slave_dev; | 1384 | new_slave->dev = slave_dev; |
| 1385 | slave_dev->priv_flags |= IFF_BONDING; | ||
| 1368 | 1386 | ||
| 1369 | if ((bond->params.mode == BOND_MODE_TLB) || | 1387 | if ((bond->params.mode == BOND_MODE_TLB) || |
| 1370 | (bond->params.mode == BOND_MODE_ALB)) { | 1388 | (bond->params.mode == BOND_MODE_ALB)) { |
| @@ -1417,6 +1435,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1417 | 1435 | ||
| 1418 | bond_compute_features(bond); | 1436 | bond_compute_features(bond); |
| 1419 | 1437 | ||
| 1438 | new_slave->last_arp_rx = jiffies; | ||
| 1439 | |||
| 1420 | if (bond->params.miimon && !bond->params.use_carrier) { | 1440 | if (bond->params.miimon && !bond->params.use_carrier) { |
| 1421 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1441 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
| 1422 | 1442 | ||
| @@ -1493,29 +1513,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1493 | 1513 | ||
| 1494 | switch (bond->params.mode) { | 1514 | switch (bond->params.mode) { |
| 1495 | case BOND_MODE_ACTIVEBACKUP: | 1515 | case BOND_MODE_ACTIVEBACKUP: |
| 1496 | /* if we're in active-backup mode, we need one and | 1516 | bond_set_slave_inactive_flags(new_slave); |
| 1497 | * only one active interface. The backup interfaces | 1517 | bond_select_active_slave(bond); |
| 1498 | * will have their SLAVE_INACTIVE flag set because we | ||
| 1499 | * need them to be drop all packets. Thus, since we | ||
| 1500 | * guarantee that curr_active_slave always point to | ||
| 1501 | * the last usable interface, we just have to verify | ||
| 1502 | * this interface's flag. | ||
| 1503 | */ | ||
| 1504 | if (((!bond->curr_active_slave) || | ||
| 1505 | (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && | ||
| 1506 | (new_slave->link != BOND_LINK_DOWN)) { | ||
| 1507 | /* first slave or no active slave yet, and this link | ||
| 1508 | is OK, so make this interface the active one */ | ||
| 1509 | bond_change_active_slave(bond, new_slave); | ||
| 1510 | printk(KERN_INFO DRV_NAME | ||
| 1511 | ": %s: first active interface up!\n", | ||
| 1512 | bond->dev->name); | ||
| 1513 | netif_carrier_on(bond->dev); | ||
| 1514 | |||
| 1515 | } else { | ||
| 1516 | dprintk("This is just a backup slave\n"); | ||
| 1517 | bond_set_slave_inactive_flags(new_slave); | ||
| 1518 | } | ||
| 1519 | break; | 1518 | break; |
| 1520 | case BOND_MODE_8023AD: | 1519 | case BOND_MODE_8023AD: |
| 1521 | /* in 802.3ad mode, the internal mechanism | 1520 | /* in 802.3ad mode, the internal mechanism |
| @@ -1778,7 +1777,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1778 | dev_set_mac_address(slave_dev, &addr); | 1777 | dev_set_mac_address(slave_dev, &addr); |
| 1779 | 1778 | ||
| 1780 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1779 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
| 1781 | IFF_SLAVE_INACTIVE); | 1780 | IFF_SLAVE_INACTIVE | IFF_BONDING | |
| 1781 | IFF_SLAVE_NEEDARP); | ||
| 1782 | 1782 | ||
| 1783 | kfree(slave); | 1783 | kfree(slave); |
| 1784 | 1784 | ||
| @@ -2291,6 +2291,25 @@ static int bond_has_ip(struct bonding *bond) | |||
| 2291 | return 0; | 2291 | return 0; |
| 2292 | } | 2292 | } |
| 2293 | 2293 | ||
| 2294 | static int bond_has_this_ip(struct bonding *bond, u32 ip) | ||
| 2295 | { | ||
| 2296 | struct vlan_entry *vlan, *vlan_next; | ||
| 2297 | |||
| 2298 | if (ip == bond->master_ip) | ||
| 2299 | return 1; | ||
| 2300 | |||
| 2301 | if (list_empty(&bond->vlan_list)) | ||
| 2302 | return 0; | ||
| 2303 | |||
| 2304 | list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, | ||
| 2305 | vlan_list) { | ||
| 2306 | if (ip == vlan->vlan_ip) | ||
| 2307 | return 1; | ||
| 2308 | } | ||
| 2309 | |||
| 2310 | return 0; | ||
| 2311 | } | ||
| 2312 | |||
| 2294 | /* | 2313 | /* |
| 2295 | * We go to the (large) trouble of VLAN tagging ARP frames because | 2314 | * We go to the (large) trouble of VLAN tagging ARP frames because |
| 2296 | * switches in VLAN mode (especially if ports are configured as | 2315 | * switches in VLAN mode (especially if ports are configured as |
| @@ -2429,6 +2448,93 @@ static void bond_send_gratuitous_arp(struct bonding *bond) | |||
| 2429 | } | 2448 | } |
| 2430 | } | 2449 | } |
| 2431 | 2450 | ||
| 2451 | static void bond_validate_arp(struct bonding *bond, struct slave *slave, u32 sip, u32 tip) | ||
| 2452 | { | ||
| 2453 | int i; | ||
| 2454 | u32 *targets = bond->params.arp_targets; | ||
| 2455 | |||
| 2456 | targets = bond->params.arp_targets; | ||
| 2457 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { | ||
| 2458 | dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] " | ||
| 2459 | "%u.%u.%u.%u bhti(tip) %d\n", | ||
| 2460 | NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]), | ||
| 2461 | bond_has_this_ip(bond, tip)); | ||
| 2462 | if (sip == targets[i]) { | ||
| 2463 | if (bond_has_this_ip(bond, tip)) | ||
| 2464 | slave->last_arp_rx = jiffies; | ||
| 2465 | return; | ||
| 2466 | } | ||
| 2467 | } | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | ||
| 2471 | { | ||
| 2472 | struct arphdr *arp; | ||
| 2473 | struct slave *slave; | ||
| 2474 | struct bonding *bond; | ||
| 2475 | unsigned char *arp_ptr; | ||
| 2476 | u32 sip, tip; | ||
| 2477 | |||
| 2478 | if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) | ||
| 2479 | goto out; | ||
| 2480 | |||
| 2481 | bond = dev->priv; | ||
| 2482 | read_lock(&bond->lock); | ||
| 2483 | |||
| 2484 | dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n", | ||
| 2485 | bond->dev->name, skb->dev ? skb->dev->name : "NULL", | ||
| 2486 | orig_dev ? orig_dev->name : "NULL"); | ||
| 2487 | |||
| 2488 | slave = bond_get_slave_by_dev(bond, orig_dev); | ||
| 2489 | if (!slave || !slave_do_arp_validate(bond, slave)) | ||
| 2490 | goto out_unlock; | ||
| 2491 | |||
| 2492 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | ||
| 2493 | if (!pskb_may_pull(skb, (sizeof(struct arphdr) + | ||
| 2494 | (2 * dev->addr_len) + | ||
| 2495 | (2 * sizeof(u32))))) | ||
| 2496 | goto out_unlock; | ||
| 2497 | |||
| 2498 | arp = skb->nh.arph; | ||
| 2499 | if (arp->ar_hln != dev->addr_len || | ||
| 2500 | skb->pkt_type == PACKET_OTHERHOST || | ||
| 2501 | skb->pkt_type == PACKET_LOOPBACK || | ||
| 2502 | arp->ar_hrd != htons(ARPHRD_ETHER) || | ||
| 2503 | arp->ar_pro != htons(ETH_P_IP) || | ||
| 2504 | arp->ar_pln != 4) | ||
| 2505 | goto out_unlock; | ||
| 2506 | |||
| 2507 | arp_ptr = (unsigned char *)(arp + 1); | ||
| 2508 | arp_ptr += dev->addr_len; | ||
| 2509 | memcpy(&sip, arp_ptr, 4); | ||
| 2510 | arp_ptr += 4 + dev->addr_len; | ||
| 2511 | memcpy(&tip, arp_ptr, 4); | ||
| 2512 | |||
| 2513 | dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u" | ||
| 2514 | " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name, | ||
| 2515 | slave->state, bond->params.arp_validate, | ||
| 2516 | slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip)); | ||
| 2517 | |||
| 2518 | /* | ||
| 2519 | * Backup slaves won't see the ARP reply, but do come through | ||
| 2520 | * here for each ARP probe (so we swap the sip/tip to validate | ||
| 2521 | * the probe). In a "redundant switch, common router" type of | ||
| 2522 | * configuration, the ARP probe will (hopefully) travel from | ||
| 2523 | * the active, through one switch, the router, then the other | ||
| 2524 | * switch before reaching the backup. | ||
| 2525 | */ | ||
| 2526 | if (slave->state == BOND_STATE_ACTIVE) | ||
| 2527 | bond_validate_arp(bond, slave, sip, tip); | ||
| 2528 | else | ||
| 2529 | bond_validate_arp(bond, slave, tip, sip); | ||
| 2530 | |||
| 2531 | out_unlock: | ||
| 2532 | read_unlock(&bond->lock); | ||
| 2533 | out: | ||
| 2534 | dev_kfree_skb(skb); | ||
| 2535 | return NET_RX_SUCCESS; | ||
| 2536 | } | ||
| 2537 | |||
| 2432 | /* | 2538 | /* |
| 2433 | * this function is called regularly to monitor each slave's link | 2539 | * this function is called regularly to monitor each slave's link |
| 2434 | * ensuring that traffic is being sent and received when arp monitoring | 2540 | * ensuring that traffic is being sent and received when arp monitoring |
| @@ -2593,7 +2699,8 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2593 | */ | 2699 | */ |
| 2594 | bond_for_each_slave(bond, slave, i) { | 2700 | bond_for_each_slave(bond, slave, i) { |
| 2595 | if (slave->link != BOND_LINK_UP) { | 2701 | if (slave->link != BOND_LINK_UP) { |
| 2596 | if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) { | 2702 | if ((jiffies - slave_last_rx(bond, slave)) <= |
| 2703 | delta_in_ticks) { | ||
| 2597 | 2704 | ||
| 2598 | slave->link = BOND_LINK_UP; | 2705 | slave->link = BOND_LINK_UP; |
| 2599 | 2706 | ||
| @@ -2638,7 +2745,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2638 | 2745 | ||
| 2639 | if ((slave != bond->curr_active_slave) && | 2746 | if ((slave != bond->curr_active_slave) && |
| 2640 | (!bond->current_arp_slave) && | 2747 | (!bond->current_arp_slave) && |
| 2641 | (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && | 2748 | (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) && |
| 2642 | bond_has_ip(bond))) { | 2749 | bond_has_ip(bond))) { |
| 2643 | /* a backup slave has gone down; three times | 2750 | /* a backup slave has gone down; three times |
| 2644 | * the delta allows the current slave to be | 2751 | * the delta allows the current slave to be |
| @@ -2685,7 +2792,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2685 | * if it is up and needs to take over as the curr_active_slave | 2792 | * if it is up and needs to take over as the curr_active_slave |
| 2686 | */ | 2793 | */ |
| 2687 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 2794 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || |
| 2688 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && | 2795 | (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) && |
| 2689 | bond_has_ip(bond))) && | 2796 | bond_has_ip(bond))) && |
| 2690 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { | 2797 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { |
| 2691 | 2798 | ||
| @@ -2950,7 +3057,7 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave | |||
| 2950 | seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); | 3057 | seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); |
| 2951 | seq_printf(seq, "MII Status: %s\n", | 3058 | seq_printf(seq, "MII Status: %s\n", |
| 2952 | (slave->link == BOND_LINK_UP) ? "up" : "down"); | 3059 | (slave->link == BOND_LINK_UP) ? "up" : "down"); |
| 2953 | seq_printf(seq, "Link Failure Count: %d\n", | 3060 | seq_printf(seq, "Link Failure Count: %u\n", |
| 2954 | slave->link_failure_count); | 3061 | slave->link_failure_count); |
| 2955 | 3062 | ||
| 2956 | seq_printf(seq, | 3063 | seq_printf(seq, |
| @@ -3210,6 +3317,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v | |||
| 3210 | (event_dev ? event_dev->name : "None"), | 3317 | (event_dev ? event_dev->name : "None"), |
| 3211 | event); | 3318 | event); |
| 3212 | 3319 | ||
| 3320 | if (!(event_dev->priv_flags & IFF_BONDING)) | ||
| 3321 | return NOTIFY_DONE; | ||
| 3322 | |||
| 3213 | if (event_dev->flags & IFF_MASTER) { | 3323 | if (event_dev->flags & IFF_MASTER) { |
| 3214 | dprintk("IFF_MASTER\n"); | 3324 | dprintk("IFF_MASTER\n"); |
| 3215 | return bond_master_netdev_event(event, event_dev); | 3325 | return bond_master_netdev_event(event, event_dev); |
| @@ -3305,6 +3415,21 @@ static void bond_unregister_lacpdu(struct bonding *bond) | |||
| 3305 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); | 3415 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); |
| 3306 | } | 3416 | } |
| 3307 | 3417 | ||
| 3418 | void bond_register_arp(struct bonding *bond) | ||
| 3419 | { | ||
| 3420 | struct packet_type *pt = &bond->arp_mon_pt; | ||
| 3421 | |||
| 3422 | pt->type = htons(ETH_P_ARP); | ||
| 3423 | pt->dev = NULL; /*bond->dev;XXX*/ | ||
| 3424 | pt->func = bond_arp_rcv; | ||
| 3425 | dev_add_pack(pt); | ||
| 3426 | } | ||
| 3427 | |||
| 3428 | void bond_unregister_arp(struct bonding *bond) | ||
| 3429 | { | ||
| 3430 | dev_remove_pack(&bond->arp_mon_pt); | ||
| 3431 | } | ||
| 3432 | |||
| 3308 | /*---------------------------- Hashing Policies -----------------------------*/ | 3433 | /*---------------------------- Hashing Policies -----------------------------*/ |
| 3309 | 3434 | ||
| 3310 | /* | 3435 | /* |
| @@ -3391,6 +3516,9 @@ static int bond_open(struct net_device *bond_dev) | |||
| 3391 | } else { | 3516 | } else { |
| 3392 | arp_timer->function = (void *)&bond_loadbalance_arp_mon; | 3517 | arp_timer->function = (void *)&bond_loadbalance_arp_mon; |
| 3393 | } | 3518 | } |
| 3519 | if (bond->params.arp_validate) | ||
| 3520 | bond_register_arp(bond); | ||
| 3521 | |||
| 3394 | add_timer(arp_timer); | 3522 | add_timer(arp_timer); |
| 3395 | } | 3523 | } |
| 3396 | 3524 | ||
| @@ -3418,9 +3546,11 @@ static int bond_close(struct net_device *bond_dev) | |||
| 3418 | bond_unregister_lacpdu(bond); | 3546 | bond_unregister_lacpdu(bond); |
| 3419 | } | 3547 | } |
| 3420 | 3548 | ||
| 3549 | if (bond->params.arp_validate) | ||
| 3550 | bond_unregister_arp(bond); | ||
| 3551 | |||
| 3421 | write_lock_bh(&bond->lock); | 3552 | write_lock_bh(&bond->lock); |
| 3422 | 3553 | ||
| 3423 | bond_mc_list_destroy(bond); | ||
| 3424 | 3554 | ||
| 3425 | /* signal timers not to re-arm */ | 3555 | /* signal timers not to re-arm */ |
| 3426 | bond->kill_timers = 1; | 3556 | bond->kill_timers = 1; |
| @@ -3451,8 +3581,6 @@ static int bond_close(struct net_device *bond_dev) | |||
| 3451 | break; | 3581 | break; |
| 3452 | } | 3582 | } |
| 3453 | 3583 | ||
| 3454 | /* Release the bonded slaves */ | ||
| 3455 | bond_release_all(bond_dev); | ||
| 3456 | 3584 | ||
| 3457 | if ((bond->params.mode == BOND_MODE_TLB) || | 3585 | if ((bond->params.mode == BOND_MODE_TLB) || |
| 3458 | (bond->params.mode == BOND_MODE_ALB)) { | 3586 | (bond->params.mode == BOND_MODE_ALB)) { |
| @@ -4179,6 +4307,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
| 4179 | /* Initialize the device options */ | 4307 | /* Initialize the device options */ |
| 4180 | bond_dev->tx_queue_len = 0; | 4308 | bond_dev->tx_queue_len = 0; |
| 4181 | bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; | 4309 | bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; |
| 4310 | bond_dev->priv_flags |= IFF_BONDING; | ||
| 4182 | 4311 | ||
| 4183 | /* At first, we block adding VLANs. That's the only way to | 4312 | /* At first, we block adding VLANs. That's the only way to |
| 4184 | * prevent problems that occur when adding VLANs over an | 4313 | * prevent problems that occur when adding VLANs over an |
| @@ -4237,6 +4366,9 @@ static void bond_free_all(void) | |||
| 4237 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { | 4366 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { |
| 4238 | struct net_device *bond_dev = bond->dev; | 4367 | struct net_device *bond_dev = bond->dev; |
| 4239 | 4368 | ||
| 4369 | bond_mc_list_destroy(bond); | ||
| 4370 | /* Release the bonded slaves */ | ||
| 4371 | bond_release_all(bond_dev); | ||
| 4240 | unregister_netdevice(bond_dev); | 4372 | unregister_netdevice(bond_dev); |
| 4241 | bond_deinit(bond_dev); | 4373 | bond_deinit(bond_dev); |
| 4242 | } | 4374 | } |
| @@ -4270,6 +4402,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) | |||
| 4270 | 4402 | ||
| 4271 | static int bond_check_params(struct bond_params *params) | 4403 | static int bond_check_params(struct bond_params *params) |
| 4272 | { | 4404 | { |
| 4405 | int arp_validate_value; | ||
| 4406 | |||
| 4273 | /* | 4407 | /* |
| 4274 | * Convert string parameters. | 4408 | * Convert string parameters. |
| 4275 | */ | 4409 | */ |
| @@ -4473,6 +4607,29 @@ static int bond_check_params(struct bond_params *params) | |||
| 4473 | arp_interval = 0; | 4607 | arp_interval = 0; |
| 4474 | } | 4608 | } |
| 4475 | 4609 | ||
| 4610 | if (arp_validate) { | ||
| 4611 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 4612 | printk(KERN_ERR DRV_NAME | ||
| 4613 | ": arp_validate only supported in active-backup mode\n"); | ||
| 4614 | return -EINVAL; | ||
| 4615 | } | ||
| 4616 | if (!arp_interval) { | ||
| 4617 | printk(KERN_ERR DRV_NAME | ||
| 4618 | ": arp_validate requires arp_interval\n"); | ||
| 4619 | return -EINVAL; | ||
| 4620 | } | ||
| 4621 | |||
| 4622 | arp_validate_value = bond_parse_parm(arp_validate, | ||
| 4623 | arp_validate_tbl); | ||
| 4624 | if (arp_validate_value == -1) { | ||
| 4625 | printk(KERN_ERR DRV_NAME | ||
| 4626 | ": Error: invalid arp_validate \"%s\"\n", | ||
| 4627 | arp_validate == NULL ? "NULL" : arp_validate); | ||
| 4628 | return -EINVAL; | ||
| 4629 | } | ||
| 4630 | } else | ||
| 4631 | arp_validate_value = 0; | ||
| 4632 | |||
| 4476 | if (miimon) { | 4633 | if (miimon) { |
| 4477 | printk(KERN_INFO DRV_NAME | 4634 | printk(KERN_INFO DRV_NAME |
| 4478 | ": MII link monitoring set to %d ms\n", | 4635 | ": MII link monitoring set to %d ms\n", |
| @@ -4481,8 +4638,10 @@ static int bond_check_params(struct bond_params *params) | |||
| 4481 | int i; | 4638 | int i; |
| 4482 | 4639 | ||
| 4483 | printk(KERN_INFO DRV_NAME | 4640 | printk(KERN_INFO DRV_NAME |
| 4484 | ": ARP monitoring set to %d ms with %d target(s):", | 4641 | ": ARP monitoring set to %d ms, validate %s, with %d target(s):", |
| 4485 | arp_interval, arp_ip_count); | 4642 | arp_interval, |
| 4643 | arp_validate_tbl[arp_validate_value].modename, | ||
| 4644 | arp_ip_count); | ||
| 4486 | 4645 | ||
| 4487 | for (i = 0; i < arp_ip_count; i++) | 4646 | for (i = 0; i < arp_ip_count; i++) |
| 4488 | printk (" %s", arp_ip_target[i]); | 4647 | printk (" %s", arp_ip_target[i]); |
| @@ -4516,6 +4675,7 @@ static int bond_check_params(struct bond_params *params) | |||
| 4516 | params->xmit_policy = xmit_hashtype; | 4675 | params->xmit_policy = xmit_hashtype; |
| 4517 | params->miimon = miimon; | 4676 | params->miimon = miimon; |
| 4518 | params->arp_interval = arp_interval; | 4677 | params->arp_interval = arp_interval; |
| 4678 | params->arp_validate = arp_validate_value; | ||
| 4519 | params->updelay = updelay; | 4679 | params->updelay = updelay; |
| 4520 | params->downdelay = downdelay; | 4680 | params->downdelay = downdelay; |
| 4521 | params->use_carrier = use_carrier; | 4681 | params->use_carrier = use_carrier; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index cfe4dc3a93a3..ced9ed8f995a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -51,6 +51,7 @@ extern struct bond_params bonding_defaults; | |||
| 51 | extern struct bond_parm_tbl bond_mode_tbl[]; | 51 | extern struct bond_parm_tbl bond_mode_tbl[]; |
| 52 | extern struct bond_parm_tbl bond_lacp_tbl[]; | 52 | extern struct bond_parm_tbl bond_lacp_tbl[]; |
| 53 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; | 53 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; |
| 54 | extern struct bond_parm_tbl arp_validate_tbl[]; | ||
| 54 | 55 | ||
| 55 | static int expected_refcount = -1; | 56 | static int expected_refcount = -1; |
| 56 | static struct class *netdev_class; | 57 | static struct class *netdev_class; |
| @@ -503,6 +504,53 @@ out: | |||
| 503 | static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); | 504 | static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); |
| 504 | 505 | ||
| 505 | /* | 506 | /* |
| 507 | * Show and set arp_validate. | ||
| 508 | */ | ||
| 509 | static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf) | ||
| 510 | { | ||
| 511 | struct bonding *bond = to_bond(cd); | ||
| 512 | |||
| 513 | return sprintf(buf, "%s %d\n", | ||
| 514 | arp_validate_tbl[bond->params.arp_validate].modename, | ||
| 515 | bond->params.arp_validate) + 1; | ||
| 516 | } | ||
| 517 | |||
| 518 | static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count) | ||
| 519 | { | ||
| 520 | int new_value; | ||
| 521 | struct bonding *bond = to_bond(cd); | ||
| 522 | |||
| 523 | new_value = bond_parse_parm((char *)buf, arp_validate_tbl); | ||
| 524 | if (new_value < 0) { | ||
| 525 | printk(KERN_ERR DRV_NAME | ||
| 526 | ": %s: Ignoring invalid arp_validate value %s\n", | ||
| 527 | bond->dev->name, buf); | ||
| 528 | return -EINVAL; | ||
| 529 | } | ||
| 530 | if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
| 531 | printk(KERN_ERR DRV_NAME | ||
| 532 | ": %s: arp_validate only supported in active-backup mode.\n", | ||
| 533 | bond->dev->name); | ||
| 534 | return -EINVAL; | ||
| 535 | } | ||
| 536 | printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n", | ||
| 537 | bond->dev->name, arp_validate_tbl[new_value].modename, | ||
| 538 | new_value); | ||
| 539 | |||
| 540 | if (!bond->params.arp_validate && new_value) { | ||
| 541 | bond_register_arp(bond); | ||
| 542 | } else if (bond->params.arp_validate && !new_value) { | ||
| 543 | bond_unregister_arp(bond); | ||
| 544 | } | ||
| 545 | |||
| 546 | bond->params.arp_validate = new_value; | ||
| 547 | |||
| 548 | return count; | ||
| 549 | } | ||
| 550 | |||
| 551 | static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); | ||
| 552 | |||
| 553 | /* | ||
| 506 | * Show and set the arp timer interval. There are two tricky bits | 554 | * Show and set the arp timer interval. There are two tricky bits |
| 507 | * here. First, if ARP monitoring is activated, then we must disable | 555 | * here. First, if ARP monitoring is activated, then we must disable |
| 508 | * MII monitoring. Second, if the ARP timer isn't running, we must | 556 | * MII monitoring. Second, if the ARP timer isn't running, we must |
| @@ -914,6 +962,11 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si | |||
| 914 | "ARP monitoring. Disabling ARP monitoring...\n", | 962 | "ARP monitoring. Disabling ARP monitoring...\n", |
| 915 | bond->dev->name); | 963 | bond->dev->name); |
| 916 | bond->params.arp_interval = 0; | 964 | bond->params.arp_interval = 0; |
| 965 | if (bond->params.arp_validate) { | ||
| 966 | bond_unregister_arp(bond); | ||
| 967 | bond->params.arp_validate = | ||
| 968 | BOND_ARP_VALIDATE_NONE; | ||
| 969 | } | ||
| 917 | /* Kill ARP timer, else it brings bond's link down */ | 970 | /* Kill ARP timer, else it brings bond's link down */ |
| 918 | if (bond->mii_timer.function) { | 971 | if (bond->mii_timer.function) { |
| 919 | printk(KERN_INFO DRV_NAME | 972 | printk(KERN_INFO DRV_NAME |
| @@ -1093,7 +1146,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b | |||
| 1093 | strlen(slave->dev->name)) == 0) { | 1146 | strlen(slave->dev->name)) == 0) { |
| 1094 | old_active = bond->curr_active_slave; | 1147 | old_active = bond->curr_active_slave; |
| 1095 | new_active = slave; | 1148 | new_active = slave; |
| 1096 | if (new_active && (new_active == old_active)) { | 1149 | if (new_active == old_active) { |
| 1097 | /* do nothing */ | 1150 | /* do nothing */ |
| 1098 | printk(KERN_INFO DRV_NAME | 1151 | printk(KERN_INFO DRV_NAME |
| 1099 | ": %s: %s is already the current active slave.\n", | 1152 | ": %s: %s is already the current active slave.\n", |
| @@ -1273,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N | |||
| 1273 | static struct attribute *per_bond_attrs[] = { | 1326 | static struct attribute *per_bond_attrs[] = { |
| 1274 | &class_device_attr_slaves.attr, | 1327 | &class_device_attr_slaves.attr, |
| 1275 | &class_device_attr_mode.attr, | 1328 | &class_device_attr_mode.attr, |
| 1329 | &class_device_attr_arp_validate.attr, | ||
| 1276 | &class_device_attr_arp_interval.attr, | 1330 | &class_device_attr_arp_interval.attr, |
| 1277 | &class_device_attr_arp_ip_target.attr, | 1331 | &class_device_attr_arp_ip_target.attr, |
| 1278 | &class_device_attr_downdelay.attr, | 1332 | &class_device_attr_downdelay.attr, |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 0bdfe2c71453..dc434fb6da85 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | #include "bond_3ad.h" | 22 | #include "bond_3ad.h" |
| 23 | #include "bond_alb.h" | 23 | #include "bond_alb.h" |
| 24 | 24 | ||
| 25 | #define DRV_VERSION "3.0.3" | 25 | #define DRV_VERSION "3.1.1" |
| 26 | #define DRV_RELDATE "March 23, 2006" | 26 | #define DRV_RELDATE "September 26, 2006" |
| 27 | #define DRV_NAME "bonding" | 27 | #define DRV_NAME "bonding" |
| 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
| 29 | 29 | ||
| @@ -126,6 +126,7 @@ struct bond_params { | |||
| 126 | int xmit_policy; | 126 | int xmit_policy; |
| 127 | int miimon; | 127 | int miimon; |
| 128 | int arp_interval; | 128 | int arp_interval; |
| 129 | int arp_validate; | ||
| 129 | int use_carrier; | 130 | int use_carrier; |
| 130 | int updelay; | 131 | int updelay; |
| 131 | int downdelay; | 132 | int downdelay; |
| @@ -149,8 +150,9 @@ struct slave { | |||
| 149 | struct net_device *dev; /* first - useful for panic debug */ | 150 | struct net_device *dev; /* first - useful for panic debug */ |
| 150 | struct slave *next; | 151 | struct slave *next; |
| 151 | struct slave *prev; | 152 | struct slave *prev; |
| 152 | s16 delay; | 153 | int delay; |
| 153 | u32 jiffies; | 154 | u32 jiffies; |
| 155 | u32 last_arp_rx; | ||
| 154 | s8 link; /* one of BOND_LINK_XXXX */ | 156 | s8 link; /* one of BOND_LINK_XXXX */ |
| 155 | s8 state; /* one of BOND_STATE_XXXX */ | 157 | s8 state; /* one of BOND_STATE_XXXX */ |
| 156 | u32 original_flags; | 158 | u32 original_flags; |
| @@ -198,6 +200,7 @@ struct bonding { | |||
| 198 | struct bond_params params; | 200 | struct bond_params params; |
| 199 | struct list_head vlan_list; | 201 | struct list_head vlan_list; |
| 200 | struct vlan_group *vlgrp; | 202 | struct vlan_group *vlgrp; |
| 203 | struct packet_type arp_mon_pt; | ||
| 201 | }; | 204 | }; |
| 202 | 205 | ||
| 203 | /** | 206 | /** |
| @@ -228,6 +231,25 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | |||
| 228 | return (struct bonding *)slave->dev->master->priv; | 231 | return (struct bonding *)slave->dev->master->priv; |
| 229 | } | 232 | } |
| 230 | 233 | ||
| 234 | #define BOND_ARP_VALIDATE_NONE 0 | ||
| 235 | #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) | ||
| 236 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) | ||
| 237 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | ||
| 238 | BOND_ARP_VALIDATE_BACKUP) | ||
| 239 | |||
| 240 | extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave) | ||
| 241 | { | ||
| 242 | return bond->params.arp_validate & (1 << slave->state); | ||
| 243 | } | ||
| 244 | |||
| 245 | extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave) | ||
| 246 | { | ||
| 247 | if (slave_do_arp_validate(bond, slave)) | ||
| 248 | return slave->last_arp_rx; | ||
| 249 | |||
| 250 | return slave->dev->last_rx; | ||
| 251 | } | ||
| 252 | |||
| 231 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 253 | static inline void bond_set_slave_inactive_flags(struct slave *slave) |
| 232 | { | 254 | { |
| 233 | struct bonding *bond = slave->dev->master->priv; | 255 | struct bonding *bond = slave->dev->master->priv; |
| @@ -235,12 +257,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) | |||
| 235 | bond->params.mode != BOND_MODE_ALB) | 257 | bond->params.mode != BOND_MODE_ALB) |
| 236 | slave->state = BOND_STATE_BACKUP; | 258 | slave->state = BOND_STATE_BACKUP; |
| 237 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; | 259 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; |
| 260 | if (slave_do_arp_validate(bond, slave)) | ||
| 261 | slave->dev->priv_flags |= IFF_SLAVE_NEEDARP; | ||
| 238 | } | 262 | } |
| 239 | 263 | ||
| 240 | static inline void bond_set_slave_active_flags(struct slave *slave) | 264 | static inline void bond_set_slave_active_flags(struct slave *slave) |
| 241 | { | 265 | { |
| 242 | slave->state = BOND_STATE_ACTIVE; | 266 | slave->state = BOND_STATE_ACTIVE; |
| 243 | slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; | 267 | slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP); |
| 244 | } | 268 | } |
| 245 | 269 | ||
| 246 | static inline void bond_set_master_3ad_flags(struct bonding *bond) | 270 | static inline void bond_set_master_3ad_flags(struct bonding *bond) |
| @@ -284,6 +308,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); | |||
| 284 | const char *bond_mode_name(int mode); | 308 | const char *bond_mode_name(int mode); |
| 285 | void bond_select_active_slave(struct bonding *bond); | 309 | void bond_select_active_slave(struct bonding *bond); |
| 286 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); | 310 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); |
| 311 | void bond_register_arp(struct bonding *); | ||
| 312 | void bond_unregister_arp(struct bonding *); | ||
| 287 | 313 | ||
| 288 | #endif /* _LINUX_BONDING_H */ | 314 | #endif /* _LINUX_BONDING_H */ |
| 289 | 315 | ||
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index a170e96251f6..4020acb55005 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
| @@ -1367,8 +1367,8 @@ struct e1000_hw_stats { | |||
| 1367 | 1367 | ||
| 1368 | /* Structure containing variables used by the shared code (e1000_hw.c) */ | 1368 | /* Structure containing variables used by the shared code (e1000_hw.c) */ |
| 1369 | struct e1000_hw { | 1369 | struct e1000_hw { |
| 1370 | uint8_t *hw_addr; | 1370 | uint8_t __iomem *hw_addr; |
| 1371 | uint8_t *flash_address; | 1371 | uint8_t __iomem *flash_address; |
| 1372 | e1000_mac_type mac_type; | 1372 | e1000_mac_type mac_type; |
| 1373 | e1000_phy_type phy_type; | 1373 | e1000_phy_type phy_type; |
| 1374 | uint32_t phy_init_script; | 1374 | uint32_t phy_init_script; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 97db910fbc8c..eea1d66c530e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -3789,6 +3789,12 @@ static int nv_loopback_test(struct net_device *dev) | |||
| 3789 | /* setup packet for tx */ | 3789 | /* setup packet for tx */ |
| 3790 | pkt_len = ETH_DATA_LEN; | 3790 | pkt_len = ETH_DATA_LEN; |
| 3791 | tx_skb = dev_alloc_skb(pkt_len); | 3791 | tx_skb = dev_alloc_skb(pkt_len); |
| 3792 | if (!tx_skb) { | ||
| 3793 | printk(KERN_ERR "dev_alloc_skb() failed during loopback test" | ||
| 3794 | " of %s\n", dev->name); | ||
| 3795 | ret = 0; | ||
| 3796 | goto out; | ||
| 3797 | } | ||
| 3792 | pkt_data = skb_put(tx_skb, pkt_len); | 3798 | pkt_data = skb_put(tx_skb, pkt_len); |
| 3793 | for (i = 0; i < pkt_len; i++) | 3799 | for (i = 0; i < pkt_len; i++) |
| 3794 | pkt_data[i] = (u8)(i & 0xff); | 3800 | pkt_data[i] = (u8)(i & 0xff); |
| @@ -3853,7 +3859,7 @@ static int nv_loopback_test(struct net_device *dev) | |||
| 3853 | tx_skb->end-tx_skb->data, | 3859 | tx_skb->end-tx_skb->data, |
| 3854 | PCI_DMA_TODEVICE); | 3860 | PCI_DMA_TODEVICE); |
| 3855 | dev_kfree_skb_any(tx_skb); | 3861 | dev_kfree_skb_any(tx_skb); |
| 3856 | 3862 | out: | |
| 3857 | /* stop engines */ | 3863 | /* stop engines */ |
| 3858 | nv_stop_rx(dev); | 3864 | nv_stop_rx(dev); |
| 3859 | nv_stop_tx(dev); | 3865 | nv_stop_tx(dev); |
diff --git a/drivers/net/gt64240eth.h b/drivers/net/gt64240eth.h deleted file mode 100644 index 0d6f486e4579..000000000000 --- a/drivers/net/gt64240eth.h +++ /dev/null | |||
| @@ -1,402 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001 Patton Electronics Company | ||
| 7 | * Copyright (C) 2002 Momentum Computer | ||
| 8 | * | ||
| 9 | * Copyright 2000 MontaVista Software Inc. | ||
| 10 | * Author: MontaVista Software, Inc. | ||
| 11 | * stevel@mvista.com or support@mvista.com | ||
| 12 | * | ||
| 13 | * This program is free software; you can distribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License (Version 2) as | ||
| 15 | * published by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 20 | * for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License along | ||
| 23 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 24 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 25 | * | ||
| 26 | * Ethernet driver definitions for the MIPS GT96100 Advanced | ||
| 27 | * Communication Controller. | ||
| 28 | * | ||
| 29 | * Modified for the Marvellous GT64240 Retarded Communication Controller. | ||
| 30 | */ | ||
| 31 | #ifndef _GT64240ETH_H | ||
| 32 | #define _GT64240ETH_H | ||
| 33 | |||
| 34 | #include <asm/gt64240.h> | ||
| 35 | |||
| 36 | #define ETHERNET_PORTS_DIFFERENCE_OFFSETS 0x400 | ||
| 37 | |||
| 38 | /* Translate those weanie names from Galileo/VxWorks header files: */ | ||
| 39 | |||
| 40 | #define GT64240_MRR MAIN_ROUTING_REGISTER | ||
| 41 | #define GT64240_CIU_ARBITER_CONFIG COMM_UNIT_ARBITER_CONFIGURATION_REGISTER | ||
| 42 | #define GT64240_CIU_ARBITER_CONTROL COMM_UNIT_ARBITER_CONTROL | ||
| 43 | #define GT64240_MAIN_LOW_CAUSE LOW_INTERRUPT_CAUSE_REGISTER | ||
| 44 | #define GT64240_MAIN_HIGH_CAUSE HIGH_INTERRUPT_CAUSE_REGISTER | ||
| 45 | #define GT64240_CPU_LOW_MASK CPU_INTERRUPT_MASK_REGISTER_LOW | ||
| 46 | #define GT64240_CPU_HIGH_MASK CPU_INTERRUPT_MASK_REGISTER_HIGH | ||
| 47 | #define GT64240_CPU_SELECT_CAUSE CPU_SELECT_CAUSE_REGISTER | ||
| 48 | |||
| 49 | #define GT64240_ETH_PHY_ADDR_REG ETHERNET_PHY_ADDRESS_REGISTER | ||
| 50 | #define GT64240_ETH_PORT_CONFIG ETHERNET0_PORT_CONFIGURATION_REGISTER | ||
| 51 | #define GT64240_ETH_PORT_CONFIG_EXT ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER | ||
| 52 | #define GT64240_ETH_PORT_COMMAND ETHERNET0_PORT_COMMAND_REGISTER | ||
| 53 | #define GT64240_ETH_PORT_STATUS ETHERNET0_PORT_STATUS_REGISTER | ||
| 54 | #define GT64240_ETH_IO_SIZE ETHERNET_PORTS_DIFFERENCE_OFFSETS | ||
| 55 | #define GT64240_ETH_SMI_REG ETHERNET_SMI_REGISTER | ||
| 56 | #define GT64240_ETH_MIB_COUNT_BASE ETHERNET0_MIB_COUNTER_BASE | ||
| 57 | #define GT64240_ETH_SDMA_CONFIG ETHERNET0_SDMA_CONFIGURATION_REGISTER | ||
| 58 | #define GT64240_ETH_SDMA_COMM ETHERNET0_SDMA_COMMAND_REGISTER | ||
| 59 | #define GT64240_ETH_INT_MASK ETHERNET0_INTERRUPT_MASK_REGISTER | ||
| 60 | #define GT64240_ETH_INT_CAUSE ETHERNET0_INTERRUPT_CAUSE_REGISTER | ||
| 61 | #define GT64240_ETH_CURR_TX_DESC_PTR0 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 | ||
| 62 | #define GT64240_ETH_CURR_TX_DESC_PTR1 ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 | ||
| 63 | #define GT64240_ETH_1ST_RX_DESC_PTR0 ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 | ||
| 64 | #define GT64240_ETH_CURR_RX_DESC_PTR0 ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 | ||
| 65 | #define GT64240_ETH_HASH_TBL_PTR ETHERNET0_HASH_TABLE_POINTER_REGISTER | ||
| 66 | |||
| 67 | /* Turn on NAPI by default */ | ||
| 68 | |||
| 69 | #define GT64240_NAPI 1 | ||
| 70 | |||
| 71 | /* Some 64240 settings that SHOULD eventually be setup in PROM monitor: */ | ||
| 72 | /* (Board-specific to the DSL3224 Rev A board ONLY!) */ | ||
| 73 | #define D3224_MPP_CTRL0_SETTING 0x66669900 | ||
| 74 | #define D3224_MPP_CTRL1_SETTING 0x00000000 | ||
| 75 | #define D3224_MPP_CTRL2_SETTING 0x00887700 | ||
| 76 | #define D3224_MPP_CTRL3_SETTING 0x00000044 | ||
| 77 | #define D3224_GPP_IO_CTRL_SETTING 0x0000e800 | ||
| 78 | #define D3224_GPP_LEVEL_CTRL_SETTING 0xf001f703 | ||
| 79 | #define D3224_GPP_VALUE_SETTING 0x00000000 | ||
| 80 | |||
| 81 | /* Keep the ring sizes a power of two for efficiency. */ | ||
| 82 | //-#define TX_RING_SIZE 16 | ||
| 83 | #define TX_RING_SIZE 64 /* TESTING !!! */ | ||
| 84 | #define RX_RING_SIZE 32 | ||
| 85 | #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ | ||
| 86 | |||
| 87 | #define RX_HASH_TABLE_SIZE 16384 | ||
| 88 | #define HASH_HOP_NUMBER 12 | ||
| 89 | |||
| 90 | #define NUM_INTERFACES 3 | ||
| 91 | |||
| 92 | #define GT64240ETH_TX_TIMEOUT HZ/4 | ||
| 93 | |||
| 94 | #define MIPS_GT64240_BASE 0xf4000000 | ||
| 95 | #define GT64240_ETH0_BASE (MIPS_GT64240_BASE + GT64240_ETH_PORT_CONFIG) | ||
| 96 | #define GT64240_ETH1_BASE (GT64240_ETH0_BASE + GT64240_ETH_IO_SIZE) | ||
| 97 | #define GT64240_ETH2_BASE (GT64240_ETH1_BASE + GT64240_ETH_IO_SIZE) | ||
| 98 | |||
| 99 | #if defined(CONFIG_MIPS_DSL3224) | ||
| 100 | #define GT64240_ETHER0_IRQ 4 | ||
| 101 | #define GT64240_ETHER1_IRQ 4 | ||
| 102 | #else | ||
| 103 | #define GT64240_ETHER0_IRQ -1 | ||
| 104 | #define GT64240_ETHER1_IRQ -1 | ||
| 105 | #endif | ||
| 106 | |||
| 107 | #define REV_GT64240 0x1 | ||
| 108 | #define REV_GT64240A 0x10 | ||
| 109 | |||
| 110 | #define GT64240ETH_READ(gp, offset) \ | ||
| 111 | GT_READ((gp)->port_offset + (offset)) | ||
| 112 | |||
| 113 | #define GT64240ETH_WRITE(gp, offset, data) \ | ||
| 114 | GT_WRITE((gp)->port_offset + (offset), (data)) | ||
| 115 | |||
| 116 | #define GT64240ETH_SETBIT(gp, offset, bits) \ | ||
| 117 | GT64240ETH_WRITE((gp), (offset), \ | ||
| 118 | GT64240ETH_READ((gp), (offset)) | (bits)) | ||
| 119 | |||
| 120 | #define GT64240ETH_CLRBIT(gp, offset, bits) \ | ||
| 121 | GT64240ETH_WRITE((gp), (offset), \ | ||
| 122 | GT64240ETH_READ((gp), (offset)) & ~(bits)) | ||
| 123 | |||
| 124 | #define GT64240_READ(ofs) GT_READ(ofs) | ||
| 125 | #define GT64240_WRITE(ofs, data) GT_WRITE((ofs), (data)) | ||
| 126 | |||
| 127 | /* Bit definitions of the SMI Reg */ | ||
| 128 | enum { | ||
| 129 | smirDataMask = 0xffff, | ||
| 130 | smirPhyAdMask = 0x1f << 16, | ||
| 131 | smirPhyAdBit = 16, | ||
| 132 | smirRegAdMask = 0x1f << 21, | ||
| 133 | smirRegAdBit = 21, | ||
| 134 | smirOpCode = 1 << 26, | ||
| 135 | smirReadValid = 1 << 27, | ||
| 136 | smirBusy = 1 << 28 | ||
| 137 | }; | ||
| 138 | |||
| 139 | /* Bit definitions of the Port Config Reg */ | ||
| 140 | enum pcr_bits { | ||
| 141 | pcrPM = 1 << 0, | ||
| 142 | pcrRBM = 1 << 1, | ||
| 143 | pcrPBF = 1 << 2, | ||
| 144 | pcrEN = 1 << 7, | ||
| 145 | pcrLPBKMask = 0x3 << 8, | ||
| 146 | pcrLPBKBit = 1 << 8, | ||
| 147 | pcrFC = 1 << 10, | ||
| 148 | pcrHS = 1 << 12, | ||
| 149 | pcrHM = 1 << 13, | ||
| 150 | pcrHDM = 1 << 14, | ||
| 151 | pcrHD = 1 << 15, | ||
| 152 | pcrISLMask = 0x7 << 28, | ||
| 153 | pcrISLBit = 28, | ||
| 154 | pcrACCS = 1 << 31 | ||
| 155 | }; | ||
| 156 | |||
| 157 | /* Bit definitions of the Port Config Extend Reg */ | ||
| 158 | enum pcxr_bits { | ||
| 159 | pcxrIGMP = 1, | ||
| 160 | pcxrSPAN = 2, | ||
| 161 | pcxrPAR = 4, | ||
| 162 | pcxrPRIOtxMask = 0x7 << 3, | ||
| 163 | pcxrPRIOtxBit = 3, | ||
| 164 | pcxrPRIOrxMask = 0x3 << 6, | ||
| 165 | pcxrPRIOrxBit = 6, | ||
| 166 | pcxrPRIOrxOverride = 1 << 8, | ||
| 167 | pcxrDPLXen = 1 << 9, | ||
| 168 | pcxrFCTLen = 1 << 10, | ||
| 169 | pcxrFLP = 1 << 11, | ||
| 170 | pcxrFCTL = 1 << 12, | ||
| 171 | pcxrMFLMask = 0x3 << 14, | ||
| 172 | pcxrMFLBit = 14, | ||
| 173 | pcxrMIBclrMode = 1 << 16, | ||
| 174 | pcxrSpeed = 1 << 18, | ||
| 175 | pcxrSpeeden = 1 << 19, | ||
| 176 | pcxrRMIIen = 1 << 20, | ||
| 177 | pcxrDSCPen = 1 << 21 | ||
| 178 | }; | ||
| 179 | |||
| 180 | /* Bit definitions of the Port Command Reg */ | ||
| 181 | enum pcmr_bits { | ||
| 182 | pcmrFJ = 1 << 15 | ||
| 183 | }; | ||
| 184 | |||
| 185 | |||
| 186 | /* Bit definitions of the Port Status Reg */ | ||
| 187 | enum psr_bits { | ||
| 188 | psrSpeed = 1, | ||
| 189 | psrDuplex = 2, | ||
| 190 | psrFctl = 4, | ||
| 191 | psrLink = 8, | ||
| 192 | psrPause = 1 << 4, | ||
| 193 | psrTxLow = 1 << 5, | ||
| 194 | psrTxHigh = 1 << 6, | ||
| 195 | psrTxInProg = 1 << 7 | ||
| 196 | }; | ||
| 197 | |||
| 198 | /* Bit definitions of the SDMA Config Reg */ | ||
| 199 | enum sdcr_bits { | ||
| 200 | sdcrRCMask = 0xf << 2, | ||
| 201 | sdcrRCBit = 2, | ||
| 202 | sdcrBLMR = 1 << 6, | ||
| 203 | sdcrBLMT = 1 << 7, | ||
| 204 | sdcrPOVR = 1 << 8, | ||
| 205 | sdcrRIFB = 1 << 9, | ||
| 206 | sdcrBSZMask = 0x3 << 12, | ||
| 207 | sdcrBSZBit = 12 | ||
| 208 | }; | ||
| 209 | |||
| 210 | /* Bit definitions of the SDMA Command Reg */ | ||
| 211 | enum sdcmr_bits { | ||
| 212 | sdcmrERD = 1 << 7, | ||
| 213 | sdcmrAR = 1 << 15, | ||
| 214 | sdcmrSTDH = 1 << 16, | ||
| 215 | sdcmrSTDL = 1 << 17, | ||
| 216 | sdcmrTXDH = 1 << 23, | ||
| 217 | sdcmrTXDL = 1 << 24, | ||
| 218 | sdcmrAT = 1 << 31 | ||
| 219 | }; | ||
| 220 | |||
| 221 | /* Bit definitions of the Interrupt Cause Reg */ | ||
| 222 | enum icr_bits { | ||
| 223 | icrRxBuffer = 1, | ||
| 224 | icrTxBufferHigh = 1 << 2, | ||
| 225 | icrTxBufferLow = 1 << 3, | ||
| 226 | icrTxEndHigh = 1 << 6, | ||
| 227 | icrTxEndLow = 1 << 7, | ||
| 228 | icrRxError = 1 << 8, | ||
| 229 | icrTxErrorHigh = 1 << 10, | ||
| 230 | icrTxErrorLow = 1 << 11, | ||
| 231 | icrRxOVR = 1 << 12, | ||
| 232 | icrTxUdr = 1 << 13, | ||
| 233 | icrRxBufferQ0 = 1 << 16, | ||
| 234 | icrRxBufferQ1 = 1 << 17, | ||
| 235 | icrRxBufferQ2 = 1 << 18, | ||
| 236 | icrRxBufferQ3 = 1 << 19, | ||
| 237 | icrRxErrorQ0 = 1 << 20, | ||
| 238 | icrRxErrorQ1 = 1 << 21, | ||
| 239 | icrRxErrorQ2 = 1 << 22, | ||
| 240 | icrRxErrorQ3 = 1 << 23, | ||
| 241 | icrMIIPhySTC = 1 << 28, | ||
| 242 | icrSMIdone = 1 << 29, | ||
| 243 | icrEtherIntSum = 1 << 31 | ||
| 244 | }; | ||
| 245 | |||
| 246 | |||
| 247 | /* The Rx and Tx descriptor lists. */ | ||
| 248 | #ifdef __LITTLE_ENDIAN | ||
| 249 | typedef struct { | ||
| 250 | u32 cmdstat; | ||
| 251 | u16 reserved; //-prk21aug01 u32 reserved:16; | ||
| 252 | u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; | ||
| 253 | u32 buff_ptr; | ||
| 254 | u32 next; | ||
| 255 | } gt64240_td_t; | ||
| 256 | |||
| 257 | typedef struct { | ||
| 258 | u32 cmdstat; | ||
| 259 | u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; | ||
| 260 | u16 buff_sz; //-prk21aug01 u32 buff_sz:16; | ||
| 261 | u32 buff_ptr; | ||
| 262 | u32 next; | ||
| 263 | } gt64240_rd_t; | ||
| 264 | #elif defined(__BIG_ENDIAN) | ||
| 265 | typedef struct { | ||
| 266 | u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; | ||
| 267 | u16 reserved; //-prk21aug01 u32 reserved:16; | ||
| 268 | u32 cmdstat; | ||
| 269 | u32 next; | ||
| 270 | u32 buff_ptr; | ||
| 271 | } gt64240_td_t; | ||
| 272 | |||
| 273 | typedef struct { | ||
| 274 | u16 buff_sz; //-prk21aug01 u32 buff_sz:16; | ||
| 275 | u16 byte_cnt; //-prk21aug01 u32 byte_cnt:16; | ||
| 276 | u32 cmdstat; | ||
| 277 | u32 next; | ||
| 278 | u32 buff_ptr; | ||
| 279 | } gt64240_rd_t; | ||
| 280 | #else | ||
| 281 | #error Either __BIG_ENDIAN or __LITTLE_ENDIAN must be defined! | ||
| 282 | #endif | ||
| 283 | |||
| 284 | |||
| 285 | /* Values for the Tx command-status descriptor entry. */ | ||
| 286 | enum td_cmdstat { | ||
| 287 | txOwn = 1 << 31, | ||
| 288 | txAutoMode = 1 << 30, | ||
| 289 | txEI = 1 << 23, | ||
| 290 | txGenCRC = 1 << 22, | ||
| 291 | txPad = 1 << 18, | ||
| 292 | txFirst = 1 << 17, | ||
| 293 | txLast = 1 << 16, | ||
| 294 | txErrorSummary = 1 << 15, | ||
| 295 | txReTxCntMask = 0x0f << 10, | ||
| 296 | txReTxCntBit = 10, | ||
| 297 | txCollision = 1 << 9, | ||
| 298 | txReTxLimit = 1 << 8, | ||
| 299 | txUnderrun = 1 << 6, | ||
| 300 | txLateCollision = 1 << 5 | ||
| 301 | }; | ||
| 302 | |||
| 303 | |||
| 304 | /* Values for the Rx command-status descriptor entry. */ | ||
| 305 | enum rd_cmdstat { | ||
| 306 | rxOwn = 1 << 31, | ||
| 307 | rxAutoMode = 1 << 30, | ||
| 308 | rxEI = 1 << 23, | ||
| 309 | rxFirst = 1 << 17, | ||
| 310 | rxLast = 1 << 16, | ||
| 311 | rxErrorSummary = 1 << 15, | ||
| 312 | rxIGMP = 1 << 14, | ||
| 313 | rxHashExpired = 1 << 13, | ||
| 314 | rxMissedFrame = 1 << 12, | ||
| 315 | rxFrameType = 1 << 11, | ||
| 316 | rxShortFrame = 1 << 8, | ||
| 317 | rxMaxFrameLen = 1 << 7, | ||
| 318 | rxOverrun = 1 << 6, | ||
| 319 | rxCollision = 1 << 4, | ||
| 320 | rxCRCError = 1 | ||
| 321 | }; | ||
| 322 | |||
| 323 | /* Bit fields of a Hash Table Entry */ | ||
| 324 | enum hash_table_entry { | ||
| 325 | hteValid = 1, | ||
| 326 | hteSkip = 2, | ||
| 327 | hteRD = 4 | ||
| 328 | }; | ||
| 329 | |||
| 330 | // The MIB counters | ||
| 331 | typedef struct { | ||
| 332 | u32 byteReceived; | ||
| 333 | u32 byteSent; | ||
| 334 | u32 framesReceived; | ||
| 335 | u32 framesSent; | ||
| 336 | u32 totalByteReceived; | ||
| 337 | u32 totalFramesReceived; | ||
| 338 | u32 broadcastFramesReceived; | ||
| 339 | u32 multicastFramesReceived; | ||
| 340 | u32 cRCError; | ||
| 341 | u32 oversizeFrames; | ||
| 342 | u32 fragments; | ||
| 343 | u32 jabber; | ||
| 344 | u32 collision; | ||
| 345 | u32 lateCollision; | ||
| 346 | u32 frames64; | ||
| 347 | u32 frames65_127; | ||
| 348 | u32 frames128_255; | ||
| 349 | u32 frames256_511; | ||
| 350 | u32 frames512_1023; | ||
| 351 | u32 frames1024_MaxSize; | ||
| 352 | u32 macRxError; | ||
| 353 | u32 droppedFrames; | ||
| 354 | u32 outMulticastFrames; | ||
| 355 | u32 outBroadcastFrames; | ||
| 356 | u32 undersizeFrames; | ||
| 357 | } mib_counters_t; | ||
| 358 | |||
| 359 | |||
| 360 | struct gt64240_private { | ||
| 361 | gt64240_rd_t *rx_ring; | ||
| 362 | gt64240_td_t *tx_ring; | ||
| 363 | // The Rx and Tx rings must be 16-byte aligned | ||
| 364 | dma_addr_t rx_ring_dma; | ||
| 365 | dma_addr_t tx_ring_dma; | ||
| 366 | char *hash_table; | ||
| 367 | // The Hash Table must be 8-byte aligned | ||
| 368 | dma_addr_t hash_table_dma; | ||
| 369 | int hash_mode; | ||
| 370 | |||
| 371 | // The Rx buffers must be 8-byte aligned | ||
| 372 | char *rx_buff; | ||
| 373 | dma_addr_t rx_buff_dma; | ||
| 374 | // Tx buffers (tx_skbuff[i]->data) with less than 8 bytes | ||
| 375 | // of payload must be 8-byte aligned | ||
| 376 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | ||
| 377 | int rx_next_out; /* The next free ring entry to receive */ | ||
| 378 | int tx_next_in; /* The next free ring entry to send */ | ||
| 379 | int tx_next_out; /* The last ring entry the ISR processed */ | ||
| 380 | int tx_count; /* current # of pkts waiting to be sent in Tx ring */ | ||
| 381 | int intr_work_done; /* number of Rx and Tx pkts processed in the isr */ | ||
| 382 | int tx_full; /* Tx ring is full */ | ||
| 383 | |||
| 384 | mib_counters_t mib; | ||
| 385 | struct net_device_stats stats; | ||
| 386 | |||
| 387 | int io_size; | ||
| 388 | int port_num; // 0 or 1 | ||
| 389 | u32 port_offset; | ||
| 390 | |||
| 391 | int phy_addr; // PHY address | ||
| 392 | u32 last_psr; // last value of the port status register | ||
| 393 | |||
| 394 | int options; /* User-settable misc. driver options. */ | ||
| 395 | int drv_flags; | ||
| 396 | spinlock_t lock; /* Serialise access to device */ | ||
| 397 | struct mii_if_info mii_if; | ||
| 398 | |||
| 399 | u32 msg_enable; | ||
| 400 | }; | ||
| 401 | |||
| 402 | #endif /* _GT64240ETH_H */ | ||
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 2a0d538b387f..383cef1f5999 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
| @@ -671,10 +671,8 @@ static void irda_usb_net_timeout(struct net_device *netdev) | |||
| 671 | * Jean II */ | 671 | * Jean II */ |
| 672 | done = 1; | 672 | done = 1; |
| 673 | break; | 673 | break; |
| 674 | case -ECONNABORTED: /* -103 */ | 674 | case -ECONNRESET: |
| 675 | case -ECONNRESET: /* -104 */ | 675 | case -ENOENT: /* urb unlinked by us */ |
| 676 | case -ETIMEDOUT: /* -110 */ | ||
| 677 | case -ENOENT: /* -2 (urb unlinked by us) */ | ||
| 678 | default: /* ??? - Play safe */ | 676 | default: /* ??? - Play safe */ |
| 679 | urb->status = 0; | 677 | urb->status = 0; |
| 680 | netif_wake_queue(self->netdev); | 678 | netif_wake_queue(self->netdev); |
| @@ -712,10 +710,8 @@ static void irda_usb_net_timeout(struct net_device *netdev) | |||
| 712 | * Jean II */ | 710 | * Jean II */ |
| 713 | done = 1; | 711 | done = 1; |
| 714 | break; | 712 | break; |
| 715 | case -ECONNABORTED: /* -103 */ | 713 | case -ECONNRESET: |
| 716 | case -ECONNRESET: /* -104 */ | 714 | case -ENOENT: /* urb unlinked by us */ |
| 717 | case -ETIMEDOUT: /* -110 */ | ||
| 718 | case -ENOENT: /* -2 (urb unlinked by us) */ | ||
| 719 | default: /* ??? - Play safe */ | 715 | default: /* ??? - Play safe */ |
| 720 | if(skb != NULL) { | 716 | if(skb != NULL) { |
| 721 | dev_kfree_skb_any(skb); | 717 | dev_kfree_skb_any(skb); |
| @@ -845,14 +841,14 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
| 845 | self->stats.rx_crc_errors++; | 841 | self->stats.rx_crc_errors++; |
| 846 | /* Also precursor to a hot-unplug on UHCI. */ | 842 | /* Also precursor to a hot-unplug on UHCI. */ |
| 847 | /* Fallthrough... */ | 843 | /* Fallthrough... */ |
| 848 | case -ECONNRESET: /* -104 */ | 844 | case -ECONNRESET: |
| 849 | /* Random error, if I remember correctly */ | 845 | /* Random error, if I remember correctly */ |
| 850 | /* uhci_cleanup_unlink() is going to kill the Rx | 846 | /* uhci_cleanup_unlink() is going to kill the Rx |
| 851 | * URB just after we return. No problem, at this | 847 | * URB just after we return. No problem, at this |
| 852 | * point the URB will be idle ;-) - Jean II */ | 848 | * point the URB will be idle ;-) - Jean II */ |
| 853 | case -ESHUTDOWN: /* -108 */ | 849 | case -ESHUTDOWN: |
| 854 | /* That's usually a hot-unplug. Submit will fail... */ | 850 | /* That's usually a hot-unplug. Submit will fail... */ |
| 855 | case -ETIMEDOUT: /* -110 */ | 851 | case -ETIME: |
| 856 | /* Usually precursor to a hot-unplug on OHCI. */ | 852 | /* Usually precursor to a hot-unplug on OHCI. */ |
| 857 | default: | 853 | default: |
| 858 | self->stats.rx_errors++; | 854 | self->stats.rx_errors++; |
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index a82a4ba8de4f..c37f0bc4c7f9 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h | |||
| @@ -58,7 +58,7 @@ typedef void irqreturn_t; | |||
| 58 | 58 | ||
| 59 | /* PDE() introduced in 2.5.4 */ | 59 | /* PDE() introduced in 2.5.4 */ |
| 60 | #ifdef CONFIG_PROC_FS | 60 | #ifdef CONFIG_PROC_FS |
| 61 | #define PDE(inode) ((inode)->u.generic_ip) | 61 | #define PDE(inode) ((inode)->i_private) |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | /* irda crc16 calculation exported in 2.5.42 */ | 64 | /* irda crc16 calculation exported in 2.5.42 */ |
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index 0fa8e4d22769..d66328975425 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c | |||
| @@ -343,6 +343,7 @@ static struct eisa_device_id ne3210_ids[] = { | |||
| 343 | { "NVL1801" }, | 343 | { "NVL1801" }, |
| 344 | { "" }, | 344 | { "" }, |
| 345 | }; | 345 | }; |
| 346 | MODULE_DEVICE_TABLE(eisa, ne3210_ids); | ||
| 346 | 347 | ||
| 347 | static struct eisa_driver ne3210_eisa_driver = { | 348 | static struct eisa_driver ne3210_eisa_driver = { |
| 348 | .id_table = ne3210_ids, | 349 | .id_table = ne3210_ids, |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2d1ecfdc80db..ecd3da151e2d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -522,7 +522,7 @@ EXPORT_SYMBOL(genphy_read_status); | |||
| 522 | 522 | ||
| 523 | static int genphy_config_init(struct phy_device *phydev) | 523 | static int genphy_config_init(struct phy_device *phydev) |
| 524 | { | 524 | { |
| 525 | u32 val; | 525 | int val; |
| 526 | u32 features; | 526 | u32 features; |
| 527 | 527 | ||
| 528 | /* For now, I'll claim that the generic driver supports | 528 | /* For now, I'll claim that the generic driver supports |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index f5dbeb27b6f0..1bf23e41f580 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -2904,7 +2904,7 @@ static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device | |||
| 2904 | { | 2904 | { |
| 2905 | u64 val64 = 0x0; | 2905 | u64 val64 = 0x0; |
| 2906 | nic_t *sp = dev->priv; | 2906 | nic_t *sp = dev->priv; |
| 2907 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | 2907 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
| 2908 | 2908 | ||
| 2909 | //address transaction | 2909 | //address transaction |
| 2910 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | 2910 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) |
| @@ -2953,7 +2953,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) | |||
| 2953 | u64 val64 = 0x0; | 2953 | u64 val64 = 0x0; |
| 2954 | u64 rval64 = 0x0; | 2954 | u64 rval64 = 0x0; |
| 2955 | nic_t *sp = dev->priv; | 2955 | nic_t *sp = dev->priv; |
| 2956 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | 2956 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
| 2957 | 2957 | ||
| 2958 | /* address transaction */ | 2958 | /* address transaction */ |
| 2959 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | 2959 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) |
| @@ -3276,7 +3276,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 3276 | * SUCCESS on success and FAILURE on failure. | 3276 | * SUCCESS on success and FAILURE on failure. |
| 3277 | */ | 3277 | */ |
| 3278 | 3278 | ||
| 3279 | static int wait_for_cmd_complete(void *addr, u64 busy_bit) | 3279 | static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit) |
| 3280 | { | 3280 | { |
| 3281 | int ret = FAILURE, cnt = 0; | 3281 | int ret = FAILURE, cnt = 0; |
| 3282 | u64 val64; | 3282 | u64 val64; |
| @@ -4303,11 +4303,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev) | |||
| 4303 | sp->stats.tx_errors = | 4303 | sp->stats.tx_errors = |
| 4304 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); | 4304 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); |
| 4305 | sp->stats.rx_errors = | 4305 | sp->stats.rx_errors = |
| 4306 | le32_to_cpu(mac_control->stats_info->rmac_drop_frms); | 4306 | le64_to_cpu(mac_control->stats_info->rmac_drop_frms); |
| 4307 | sp->stats.multicast = | 4307 | sp->stats.multicast = |
| 4308 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); | 4308 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); |
| 4309 | sp->stats.rx_length_errors = | 4309 | sp->stats.rx_length_errors = |
| 4310 | le32_to_cpu(mac_control->stats_info->rmac_long_frms); | 4310 | le64_to_cpu(mac_control->stats_info->rmac_long_frms); |
| 4311 | 4311 | ||
| 4312 | return (&sp->stats); | 4312 | return (&sp->stats); |
| 4313 | } | 4313 | } |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 9142d91355bc..705e9a8fa30f 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #define TX_WATCHDOG (5 * HZ) | 58 | #define TX_WATCHDOG (5 * HZ) |
| 59 | #define NAPI_WEIGHT 64 | 59 | #define NAPI_WEIGHT 64 |
| 60 | #define BLINK_MS 250 | 60 | #define BLINK_MS 250 |
| 61 | #define LINK_HZ (HZ/2) | ||
| 61 | 62 | ||
| 62 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); | 63 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); |
| 63 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); | 64 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); |
| @@ -605,7 +606,12 @@ static void skge_led(struct skge_port *skge, enum led_mode mode) | |||
| 605 | if (hw->chip_id == CHIP_ID_GENESIS) { | 606 | if (hw->chip_id == CHIP_ID_GENESIS) { |
| 606 | switch (mode) { | 607 | switch (mode) { |
| 607 | case LED_MODE_OFF: | 608 | case LED_MODE_OFF: |
| 608 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | 609 | if (hw->phy_type == SK_PHY_BCOM) |
| 610 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | ||
| 611 | else { | ||
| 612 | skge_write32(hw, SK_REG(port, TX_LED_VAL), 0); | ||
| 613 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF); | ||
| 614 | } | ||
| 609 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | 615 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); |
| 610 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | 616 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); |
| 611 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | 617 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); |
| @@ -625,8 +631,14 @@ static void skge_led(struct skge_port *skge, enum led_mode mode) | |||
| 625 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | 631 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); |
| 626 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | 632 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
| 627 | 633 | ||
| 628 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); | 634 | if (hw->phy_type == SK_PHY_BCOM) |
| 629 | break; | 635 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
| 636 | else { | ||
| 637 | skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON); | ||
| 638 | skge_write32(hw, SK_REG(port, TX_LED_VAL), 100); | ||
| 639 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); | ||
| 640 | } | ||
| 641 | |||
| 630 | } | 642 | } |
| 631 | } else { | 643 | } else { |
| 632 | switch (mode) { | 644 | switch (mode) { |
| @@ -879,6 +891,9 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) | |||
| 879 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 891 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
| 880 | *val = xm_read16(hw, port, XM_PHY_DATA); | 892 | *val = xm_read16(hw, port, XM_PHY_DATA); |
| 881 | 893 | ||
| 894 | if (hw->phy_type == SK_PHY_XMAC) | ||
| 895 | goto ready; | ||
| 896 | |||
| 882 | for (i = 0; i < PHY_RETRIES; i++) { | 897 | for (i = 0; i < PHY_RETRIES; i++) { |
| 883 | if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) | 898 | if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) |
| 884 | goto ready; | 899 | goto ready; |
| @@ -965,7 +980,8 @@ static void genesis_reset(struct skge_hw *hw, int port) | |||
| 965 | xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ | 980 | xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ |
| 966 | 981 | ||
| 967 | /* disable Broadcom PHY IRQ */ | 982 | /* disable Broadcom PHY IRQ */ |
| 968 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); | 983 | if (hw->phy_type == SK_PHY_BCOM) |
| 984 | xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); | ||
| 969 | 985 | ||
| 970 | xm_outhash(hw, port, XM_HSM, zero); | 986 | xm_outhash(hw, port, XM_HSM, zero); |
| 971 | } | 987 | } |
| @@ -1000,60 +1016,64 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
| 1000 | 1016 | ||
| 1001 | if (netif_carrier_ok(dev)) | 1017 | if (netif_carrier_ok(dev)) |
| 1002 | skge_link_down(skge); | 1018 | skge_link_down(skge); |
| 1003 | } else { | 1019 | return; |
| 1004 | if (skge->autoneg == AUTONEG_ENABLE && | 1020 | } |
| 1005 | (status & PHY_ST_AN_OVER)) { | ||
| 1006 | u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP); | ||
| 1007 | u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); | ||
| 1008 | |||
| 1009 | if (lpa & PHY_B_AN_RF) { | ||
| 1010 | printk(KERN_NOTICE PFX "%s: remote fault\n", | ||
| 1011 | dev->name); | ||
| 1012 | return; | ||
| 1013 | } | ||
| 1014 | 1021 | ||
| 1015 | /* Check Duplex mismatch */ | 1022 | if (skge->autoneg == AUTONEG_ENABLE) { |
| 1016 | switch (aux & PHY_B_AS_AN_RES_MSK) { | 1023 | u16 lpa, aux; |
| 1017 | case PHY_B_RES_1000FD: | ||
| 1018 | skge->duplex = DUPLEX_FULL; | ||
| 1019 | break; | ||
| 1020 | case PHY_B_RES_1000HD: | ||
| 1021 | skge->duplex = DUPLEX_HALF; | ||
| 1022 | break; | ||
| 1023 | default: | ||
| 1024 | printk(KERN_NOTICE PFX "%s: duplex mismatch\n", | ||
| 1025 | dev->name); | ||
| 1026 | return; | ||
| 1027 | } | ||
| 1028 | 1024 | ||
| 1025 | if (!(status & PHY_ST_AN_OVER)) | ||
| 1026 | return; | ||
| 1029 | 1027 | ||
| 1030 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | 1028 | lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP); |
| 1031 | switch (aux & PHY_B_AS_PAUSE_MSK) { | 1029 | if (lpa & PHY_B_AN_RF) { |
| 1032 | case PHY_B_AS_PAUSE_MSK: | 1030 | printk(KERN_NOTICE PFX "%s: remote fault\n", |
| 1033 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 1031 | dev->name); |
| 1034 | break; | 1032 | return; |
| 1035 | case PHY_B_AS_PRR: | 1033 | } |
| 1036 | skge->flow_control = FLOW_MODE_REM_SEND; | ||
| 1037 | break; | ||
| 1038 | case PHY_B_AS_PRT: | ||
| 1039 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
| 1040 | break; | ||
| 1041 | default: | ||
| 1042 | skge->flow_control = FLOW_MODE_NONE; | ||
| 1043 | } | ||
| 1044 | 1034 | ||
| 1045 | skge->speed = SPEED_1000; | 1035 | aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); |
| 1036 | |||
| 1037 | /* Check Duplex mismatch */ | ||
| 1038 | switch (aux & PHY_B_AS_AN_RES_MSK) { | ||
| 1039 | case PHY_B_RES_1000FD: | ||
| 1040 | skge->duplex = DUPLEX_FULL; | ||
| 1041 | break; | ||
| 1042 | case PHY_B_RES_1000HD: | ||
| 1043 | skge->duplex = DUPLEX_HALF; | ||
| 1044 | break; | ||
| 1045 | default: | ||
| 1046 | printk(KERN_NOTICE PFX "%s: duplex mismatch\n", | ||
| 1047 | dev->name); | ||
| 1048 | return; | ||
| 1046 | } | 1049 | } |
| 1047 | 1050 | ||
| 1048 | if (!netif_carrier_ok(dev)) | 1051 | |
| 1049 | genesis_link_up(skge); | 1052 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ |
| 1053 | switch (aux & PHY_B_AS_PAUSE_MSK) { | ||
| 1054 | case PHY_B_AS_PAUSE_MSK: | ||
| 1055 | skge->flow_control = FLOW_MODE_SYMMETRIC; | ||
| 1056 | break; | ||
| 1057 | case PHY_B_AS_PRR: | ||
| 1058 | skge->flow_control = FLOW_MODE_REM_SEND; | ||
| 1059 | break; | ||
| 1060 | case PHY_B_AS_PRT: | ||
| 1061 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
| 1062 | break; | ||
| 1063 | default: | ||
| 1064 | skge->flow_control = FLOW_MODE_NONE; | ||
| 1065 | } | ||
| 1066 | skge->speed = SPEED_1000; | ||
| 1050 | } | 1067 | } |
| 1068 | |||
| 1069 | if (!netif_carrier_ok(dev)) | ||
| 1070 | genesis_link_up(skge); | ||
| 1051 | } | 1071 | } |
| 1052 | 1072 | ||
| 1053 | /* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional | 1073 | /* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional |
| 1054 | * Phy on for 100 or 10Mbit operation | 1074 | * Phy on for 100 or 10Mbit operation |
| 1055 | */ | 1075 | */ |
| 1056 | static void bcom_phy_init(struct skge_port *skge, int jumbo) | 1076 | static void bcom_phy_init(struct skge_port *skge) |
| 1057 | { | 1077 | { |
| 1058 | struct skge_hw *hw = skge->hw; | 1078 | struct skge_hw *hw = skge->hw; |
| 1059 | int port = skge->port; | 1079 | int port = skge->port; |
| @@ -1144,7 +1164,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
| 1144 | phy_pause_map[skge->flow_control] | PHY_AN_CSMA); | 1164 | phy_pause_map[skge->flow_control] | PHY_AN_CSMA); |
| 1145 | 1165 | ||
| 1146 | /* Handle Jumbo frames */ | 1166 | /* Handle Jumbo frames */ |
| 1147 | if (jumbo) { | 1167 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { |
| 1148 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, | 1168 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, |
| 1149 | PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); | 1169 | PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); |
| 1150 | 1170 | ||
| @@ -1157,8 +1177,154 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
| 1157 | 1177 | ||
| 1158 | /* Use link status change interrupt */ | 1178 | /* Use link status change interrupt */ |
| 1159 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); | 1179 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); |
| 1180 | } | ||
| 1160 | 1181 | ||
| 1161 | bcom_check_link(hw, port); | 1182 | static void xm_phy_init(struct skge_port *skge) |
| 1183 | { | ||
| 1184 | struct skge_hw *hw = skge->hw; | ||
| 1185 | int port = skge->port; | ||
| 1186 | u16 ctrl = 0; | ||
| 1187 | |||
| 1188 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
| 1189 | if (skge->advertising & ADVERTISED_1000baseT_Half) | ||
| 1190 | ctrl |= PHY_X_AN_HD; | ||
| 1191 | if (skge->advertising & ADVERTISED_1000baseT_Full) | ||
| 1192 | ctrl |= PHY_X_AN_FD; | ||
| 1193 | |||
| 1194 | switch(skge->flow_control) { | ||
| 1195 | case FLOW_MODE_NONE: | ||
| 1196 | ctrl |= PHY_X_P_NO_PAUSE; | ||
| 1197 | break; | ||
| 1198 | case FLOW_MODE_LOC_SEND: | ||
| 1199 | ctrl |= PHY_X_P_ASYM_MD; | ||
| 1200 | break; | ||
| 1201 | case FLOW_MODE_SYMMETRIC: | ||
| 1202 | ctrl |= PHY_X_P_BOTH_MD; | ||
| 1203 | break; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl); | ||
| 1207 | |||
| 1208 | /* Restart Auto-negotiation */ | ||
| 1209 | ctrl = PHY_CT_ANE | PHY_CT_RE_CFG; | ||
| 1210 | } else { | ||
| 1211 | /* Set DuplexMode in Config register */ | ||
| 1212 | if (skge->duplex == DUPLEX_FULL) | ||
| 1213 | ctrl |= PHY_CT_DUP_MD; | ||
| 1214 | /* | ||
| 1215 | * Do NOT enable Auto-negotiation here. This would hold | ||
| 1216 | * the link down because no IDLEs are transmitted | ||
| 1217 | */ | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl); | ||
| 1221 | |||
| 1222 | /* Poll PHY for status changes */ | ||
| 1223 | schedule_delayed_work(&skge->link_thread, LINK_HZ); | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | static void xm_check_link(struct net_device *dev) | ||
| 1227 | { | ||
| 1228 | struct skge_port *skge = netdev_priv(dev); | ||
| 1229 | struct skge_hw *hw = skge->hw; | ||
| 1230 | int port = skge->port; | ||
| 1231 | u16 status; | ||
| 1232 | |||
| 1233 | /* read twice because of latch */ | ||
| 1234 | (void) xm_phy_read(hw, port, PHY_XMAC_STAT); | ||
| 1235 | status = xm_phy_read(hw, port, PHY_XMAC_STAT); | ||
| 1236 | |||
| 1237 | if ((status & PHY_ST_LSYNC) == 0) { | ||
| 1238 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | ||
| 1239 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
| 1240 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
| 1241 | /* dummy read to ensure writing */ | ||
| 1242 | (void) xm_read16(hw, port, XM_MMU_CMD); | ||
| 1243 | |||
| 1244 | if (netif_carrier_ok(dev)) | ||
| 1245 | skge_link_down(skge); | ||
| 1246 | return; | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | if (skge->autoneg == AUTONEG_ENABLE) { | ||
| 1250 | u16 lpa, res; | ||
| 1251 | |||
| 1252 | if (!(status & PHY_ST_AN_OVER)) | ||
| 1253 | return; | ||
| 1254 | |||
| 1255 | lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP); | ||
| 1256 | if (lpa & PHY_B_AN_RF) { | ||
| 1257 | printk(KERN_NOTICE PFX "%s: remote fault\n", | ||
| 1258 | dev->name); | ||
| 1259 | return; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI); | ||
| 1263 | |||
| 1264 | /* Check Duplex mismatch */ | ||
| 1265 | switch (res & (PHY_X_RS_HD | PHY_X_RS_FD)) { | ||
| 1266 | case PHY_X_RS_FD: | ||
| 1267 | skge->duplex = DUPLEX_FULL; | ||
| 1268 | break; | ||
| 1269 | case PHY_X_RS_HD: | ||
| 1270 | skge->duplex = DUPLEX_HALF; | ||
| 1271 | break; | ||
| 1272 | default: | ||
| 1273 | printk(KERN_NOTICE PFX "%s: duplex mismatch\n", | ||
| 1274 | dev->name); | ||
| 1275 | return; | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | ||
| 1279 | if (lpa & PHY_X_P_SYM_MD) | ||
| 1280 | skge->flow_control = FLOW_MODE_SYMMETRIC; | ||
| 1281 | else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) | ||
| 1282 | skge->flow_control = FLOW_MODE_REM_SEND; | ||
| 1283 | else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) | ||
| 1284 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
| 1285 | else | ||
| 1286 | skge->flow_control = FLOW_MODE_NONE; | ||
| 1287 | |||
| 1288 | |||
| 1289 | skge->speed = SPEED_1000; | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | if (!netif_carrier_ok(dev)) | ||
| 1293 | genesis_link_up(skge); | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | /* Poll to check for link coming up. | ||
| 1297 | * Since internal PHY is wired to a level triggered pin, can't | ||
| 1298 | * get an interrupt when carrier is detected. | ||
| 1299 | */ | ||
| 1300 | static void xm_link_timer(void *arg) | ||
| 1301 | { | ||
| 1302 | struct net_device *dev = arg; | ||
| 1303 | struct skge_port *skge = netdev_priv(arg); | ||
| 1304 | struct skge_hw *hw = skge->hw; | ||
| 1305 | int port = skge->port; | ||
| 1306 | |||
| 1307 | if (!netif_running(dev)) | ||
| 1308 | return; | ||
| 1309 | |||
| 1310 | if (netif_carrier_ok(dev)) { | ||
| 1311 | xm_read16(hw, port, XM_ISRC); | ||
| 1312 | if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)) | ||
| 1313 | goto nochange; | ||
| 1314 | } else { | ||
| 1315 | if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS) | ||
| 1316 | goto nochange; | ||
| 1317 | xm_read16(hw, port, XM_ISRC); | ||
| 1318 | if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) | ||
| 1319 | goto nochange; | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | mutex_lock(&hw->phy_mutex); | ||
| 1323 | xm_check_link(dev); | ||
| 1324 | mutex_unlock(&hw->phy_mutex); | ||
| 1325 | |||
| 1326 | nochange: | ||
| 1327 | schedule_delayed_work(&skge->link_thread, LINK_HZ); | ||
| 1162 | } | 1328 | } |
| 1163 | 1329 | ||
| 1164 | static void genesis_mac_init(struct skge_hw *hw, int port) | 1330 | static void genesis_mac_init(struct skge_hw *hw, int port) |
| @@ -1189,20 +1355,29 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
| 1189 | * namely for the 1000baseTX cards that use the XMAC's | 1355 | * namely for the 1000baseTX cards that use the XMAC's |
| 1190 | * GMII mode. | 1356 | * GMII mode. |
| 1191 | */ | 1357 | */ |
| 1192 | /* Take external Phy out of reset */ | 1358 | if (hw->phy_type != SK_PHY_XMAC) { |
| 1193 | r = skge_read32(hw, B2_GP_IO); | 1359 | /* Take external Phy out of reset */ |
| 1194 | if (port == 0) | 1360 | r = skge_read32(hw, B2_GP_IO); |
| 1195 | r |= GP_DIR_0|GP_IO_0; | 1361 | if (port == 0) |
| 1196 | else | 1362 | r |= GP_DIR_0|GP_IO_0; |
| 1197 | r |= GP_DIR_2|GP_IO_2; | 1363 | else |
| 1364 | r |= GP_DIR_2|GP_IO_2; | ||
| 1198 | 1365 | ||
| 1199 | skge_write32(hw, B2_GP_IO, r); | 1366 | skge_write32(hw, B2_GP_IO, r); |
| 1200 | 1367 | ||
| 1368 | /* Enable GMII interface */ | ||
| 1369 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | ||
| 1370 | } | ||
| 1201 | 1371 | ||
| 1202 | /* Enable GMII interface */ | ||
| 1203 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | ||
| 1204 | 1372 | ||
| 1205 | bcom_phy_init(skge, jumbo); | 1373 | switch(hw->phy_type) { |
| 1374 | case SK_PHY_XMAC: | ||
| 1375 | xm_phy_init(skge); | ||
| 1376 | break; | ||
| 1377 | case SK_PHY_BCOM: | ||
| 1378 | bcom_phy_init(skge); | ||
| 1379 | bcom_check_link(hw, port); | ||
| 1380 | } | ||
| 1206 | 1381 | ||
| 1207 | /* Set Station Address */ | 1382 | /* Set Station Address */ |
| 1208 | xm_outaddr(hw, port, XM_SA, dev->dev_addr); | 1383 | xm_outaddr(hw, port, XM_SA, dev->dev_addr); |
| @@ -1335,16 +1510,18 @@ static void genesis_stop(struct skge_port *skge) | |||
| 1335 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); | 1510 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); |
| 1336 | 1511 | ||
| 1337 | /* For external PHYs there must be special handling */ | 1512 | /* For external PHYs there must be special handling */ |
| 1338 | reg = skge_read32(hw, B2_GP_IO); | 1513 | if (hw->phy_type != SK_PHY_XMAC) { |
| 1339 | if (port == 0) { | 1514 | reg = skge_read32(hw, B2_GP_IO); |
| 1340 | reg |= GP_DIR_0; | 1515 | if (port == 0) { |
| 1341 | reg &= ~GP_IO_0; | 1516 | reg |= GP_DIR_0; |
| 1342 | } else { | 1517 | reg &= ~GP_IO_0; |
| 1343 | reg |= GP_DIR_2; | 1518 | } else { |
| 1344 | reg &= ~GP_IO_2; | 1519 | reg |= GP_DIR_2; |
| 1520 | reg &= ~GP_IO_2; | ||
| 1521 | } | ||
| 1522 | skge_write32(hw, B2_GP_IO, reg); | ||
| 1523 | skge_read32(hw, B2_GP_IO); | ||
| 1345 | } | 1524 | } |
| 1346 | skge_write32(hw, B2_GP_IO, reg); | ||
| 1347 | skge_read32(hw, B2_GP_IO); | ||
| 1348 | 1525 | ||
| 1349 | xm_write16(hw, port, XM_MMU_CMD, | 1526 | xm_write16(hw, port, XM_MMU_CMD, |
| 1350 | xm_read16(hw, port, XM_MMU_CMD) | 1527 | xm_read16(hw, port, XM_MMU_CMD) |
| @@ -1406,7 +1583,7 @@ static void genesis_link_up(struct skge_port *skge) | |||
| 1406 | struct skge_hw *hw = skge->hw; | 1583 | struct skge_hw *hw = skge->hw; |
| 1407 | int port = skge->port; | 1584 | int port = skge->port; |
| 1408 | u16 cmd; | 1585 | u16 cmd; |
| 1409 | u32 mode, msk; | 1586 | u32 mode; |
| 1410 | 1587 | ||
| 1411 | cmd = xm_read16(hw, port, XM_MMU_CMD); | 1588 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
| 1412 | 1589 | ||
| @@ -1454,27 +1631,24 @@ static void genesis_link_up(struct skge_port *skge) | |||
| 1454 | } | 1631 | } |
| 1455 | 1632 | ||
| 1456 | xm_write32(hw, port, XM_MODE, mode); | 1633 | xm_write32(hw, port, XM_MODE, mode); |
| 1457 | 1634 | xm_write16(hw, port, XM_IMSK, XM_DEF_MSK); | |
| 1458 | msk = XM_DEF_MSK; | ||
| 1459 | /* disable GP0 interrupt bit for external Phy */ | ||
| 1460 | msk |= XM_IS_INP_ASS; | ||
| 1461 | |||
| 1462 | xm_write16(hw, port, XM_IMSK, msk); | ||
| 1463 | xm_read16(hw, port, XM_ISRC); | 1635 | xm_read16(hw, port, XM_ISRC); |
| 1464 | 1636 | ||
| 1465 | /* get MMU Command Reg. */ | 1637 | /* get MMU Command Reg. */ |
| 1466 | cmd = xm_read16(hw, port, XM_MMU_CMD); | 1638 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
| 1467 | if (skge->duplex == DUPLEX_FULL) | 1639 | if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) |
| 1468 | cmd |= XM_MMU_GMII_FD; | 1640 | cmd |= XM_MMU_GMII_FD; |
| 1469 | 1641 | ||
| 1470 | /* | 1642 | /* |
| 1471 | * Workaround BCOM Errata (#10523) for all BCom Phys | 1643 | * Workaround BCOM Errata (#10523) for all BCom Phys |
| 1472 | * Enable Power Management after link up | 1644 | * Enable Power Management after link up |
| 1473 | */ | 1645 | */ |
| 1474 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, | 1646 | if (hw->phy_type == SK_PHY_BCOM) { |
| 1475 | xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) | 1647 | xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, |
| 1476 | & ~PHY_B_AC_DIS_PM); | 1648 | xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) |
| 1477 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); | 1649 | & ~PHY_B_AC_DIS_PM); |
| 1650 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); | ||
| 1651 | } | ||
| 1478 | 1652 | ||
| 1479 | /* enable Rx/Tx */ | 1653 | /* enable Rx/Tx */ |
| 1480 | xm_write16(hw, port, XM_MMU_CMD, | 1654 | xm_write16(hw, port, XM_MMU_CMD, |
| @@ -2240,6 +2414,8 @@ static int skge_down(struct net_device *dev) | |||
| 2240 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 2414 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
| 2241 | 2415 | ||
| 2242 | netif_stop_queue(dev); | 2416 | netif_stop_queue(dev); |
| 2417 | if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) | ||
| 2418 | cancel_rearming_delayed_work(&skge->link_thread); | ||
| 2243 | 2419 | ||
| 2244 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); | 2420 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); |
| 2245 | if (hw->chip_id == CHIP_ID_GENESIS) | 2421 | if (hw->chip_id == CHIP_ID_GENESIS) |
| @@ -2862,7 +3038,7 @@ static void skge_extirq(void *arg) | |||
| 2862 | if (netif_running(dev)) { | 3038 | if (netif_running(dev)) { |
| 2863 | if (hw->chip_id != CHIP_ID_GENESIS) | 3039 | if (hw->chip_id != CHIP_ID_GENESIS) |
| 2864 | yukon_phy_intr(skge); | 3040 | yukon_phy_intr(skge); |
| 2865 | else | 3041 | else if (hw->phy_type == SK_PHY_BCOM) |
| 2866 | bcom_phy_intr(skge); | 3042 | bcom_phy_intr(skge); |
| 2867 | } | 3043 | } |
| 2868 | } | 3044 | } |
| @@ -3014,7 +3190,7 @@ static int skge_reset(struct skge_hw *hw) | |||
| 3014 | { | 3190 | { |
| 3015 | u32 reg; | 3191 | u32 reg; |
| 3016 | u16 ctst, pci_status; | 3192 | u16 ctst, pci_status; |
| 3017 | u8 t8, mac_cfg, pmd_type, phy_type; | 3193 | u8 t8, mac_cfg, pmd_type; |
| 3018 | int i; | 3194 | int i; |
| 3019 | 3195 | ||
| 3020 | ctst = skge_read16(hw, B0_CTST); | 3196 | ctst = skge_read16(hw, B0_CTST); |
| @@ -3038,19 +3214,22 @@ static int skge_reset(struct skge_hw *hw) | |||
| 3038 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); | 3214 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); |
| 3039 | 3215 | ||
| 3040 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); | 3216 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); |
| 3041 | phy_type = skge_read8(hw, B2_E_1) & 0xf; | 3217 | hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; |
| 3042 | pmd_type = skge_read8(hw, B2_PMD_TYP); | 3218 | pmd_type = skge_read8(hw, B2_PMD_TYP); |
| 3043 | hw->copper = (pmd_type == 'T' || pmd_type == '1'); | 3219 | hw->copper = (pmd_type == 'T' || pmd_type == '1'); |
| 3044 | 3220 | ||
| 3045 | switch (hw->chip_id) { | 3221 | switch (hw->chip_id) { |
| 3046 | case CHIP_ID_GENESIS: | 3222 | case CHIP_ID_GENESIS: |
| 3047 | switch (phy_type) { | 3223 | switch (hw->phy_type) { |
| 3224 | case SK_PHY_XMAC: | ||
| 3225 | hw->phy_addr = PHY_ADDR_XMAC; | ||
| 3226 | break; | ||
| 3048 | case SK_PHY_BCOM: | 3227 | case SK_PHY_BCOM: |
| 3049 | hw->phy_addr = PHY_ADDR_BCOM; | 3228 | hw->phy_addr = PHY_ADDR_BCOM; |
| 3050 | break; | 3229 | break; |
| 3051 | default: | 3230 | default: |
| 3052 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", | 3231 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", |
| 3053 | pci_name(hw->pdev), phy_type); | 3232 | pci_name(hw->pdev), hw->phy_type); |
| 3054 | return -EOPNOTSUPP; | 3233 | return -EOPNOTSUPP; |
| 3055 | } | 3234 | } |
| 3056 | break; | 3235 | break; |
| @@ -3058,7 +3237,7 @@ static int skge_reset(struct skge_hw *hw) | |||
| 3058 | case CHIP_ID_YUKON: | 3237 | case CHIP_ID_YUKON: |
| 3059 | case CHIP_ID_YUKON_LITE: | 3238 | case CHIP_ID_YUKON_LITE: |
| 3060 | case CHIP_ID_YUKON_LP: | 3239 | case CHIP_ID_YUKON_LP: |
| 3061 | if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') | 3240 | if (hw->phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') |
| 3062 | hw->copper = 1; | 3241 | hw->copper = 1; |
| 3063 | 3242 | ||
| 3064 | hw->phy_addr = PHY_ADDR_MARV; | 3243 | hw->phy_addr = PHY_ADDR_MARV; |
| @@ -3089,10 +3268,13 @@ static int skge_reset(struct skge_hw *hw) | |||
| 3089 | else | 3268 | else |
| 3090 | hw->ram_size = t8 * 4096; | 3269 | hw->ram_size = t8 * 4096; |
| 3091 | 3270 | ||
| 3092 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; | 3271 | hw->intr_mask = IS_HW_ERR | IS_PORT_1; |
| 3093 | if (hw->ports > 1) | 3272 | if (hw->ports > 1) |
| 3094 | hw->intr_mask |= IS_PORT_2; | 3273 | hw->intr_mask |= IS_PORT_2; |
| 3095 | 3274 | ||
| 3275 | if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)) | ||
| 3276 | hw->intr_mask |= IS_EXT_REG; | ||
| 3277 | |||
| 3096 | if (hw->chip_id == CHIP_ID_GENESIS) | 3278 | if (hw->chip_id == CHIP_ID_GENESIS) |
| 3097 | genesis_init(hw); | 3279 | genesis_init(hw); |
| 3098 | else { | 3280 | else { |
| @@ -3226,6 +3408,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
| 3226 | 3408 | ||
| 3227 | skge->port = port; | 3409 | skge->port = port; |
| 3228 | 3410 | ||
| 3411 | /* Only used for Genesis XMAC */ | ||
| 3412 | INIT_WORK(&skge->link_thread, xm_link_timer, dev); | ||
| 3413 | |||
| 3229 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3414 | if (hw->chip_id != CHIP_ID_GENESIS) { |
| 3230 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3415 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
| 3231 | skge->rx_csum = 1; | 3416 | skge->rx_csum = 1; |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 79e09271bcf9..d0b47d46cf9d 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
| @@ -934,7 +934,7 @@ enum { | |||
| 934 | PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ | 934 | PHY_XMAC_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ |
| 935 | PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */ | 935 | PHY_XMAC_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Abi Reg */ |
| 936 | PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ | 936 | PHY_XMAC_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ |
| 937 | PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */ | 937 | PHY_XMAC_NEPG = 0x07,/* 16 bit r/w Next Page Register */ |
| 938 | PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ | 938 | PHY_XMAC_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ |
| 939 | 939 | ||
| 940 | PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */ | 940 | PHY_XMAC_EXT_STAT = 0x0f,/* 16 bit r/o Ext Status Register */ |
| @@ -1097,13 +1097,36 @@ enum { | |||
| 1097 | 1097 | ||
| 1098 | /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ | 1098 | /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ |
| 1099 | enum { | 1099 | enum { |
| 1100 | PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ | 1100 | PHY_X_P_NO_PAUSE= 0<<7,/* Bit 8..7: no Pause Mode */ |
| 1101 | PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */ | 1101 | PHY_X_P_SYM_MD = 1<<7, /* Bit 8..7: symmetric Pause Mode */ |
| 1102 | PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */ | 1102 | PHY_X_P_ASYM_MD = 2<<7,/* Bit 8..7: asymmetric Pause Mode */ |
| 1103 | PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */ | 1103 | PHY_X_P_BOTH_MD = 3<<7,/* Bit 8..7: both Pause Mode */ |
| 1104 | }; | 1104 | }; |
| 1105 | 1105 | ||
| 1106 | 1106 | ||
| 1107 | /***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/ | ||
| 1108 | enum { | ||
| 1109 | PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */ | ||
| 1110 | PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */ | ||
| 1111 | }; | ||
| 1112 | |||
| 1113 | /***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/ | ||
| 1114 | enum { | ||
| 1115 | PHY_X_RS_PAUSE = 3<<7, /* Bit 8..7: selected Pause Mode */ | ||
| 1116 | PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */ | ||
| 1117 | PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */ | ||
| 1118 | PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */ | ||
| 1119 | PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */ | ||
| 1120 | }; | ||
| 1121 | |||
| 1122 | /* Remote Fault Bits (PHY_X_AN_RFB) encoding */ | ||
| 1123 | enum { | ||
| 1124 | X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */ | ||
| 1125 | X_RFB_LF = 1<<12,/* Bit 13..12 Link Failure */ | ||
| 1126 | X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */ | ||
| 1127 | X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */ | ||
| 1128 | }; | ||
| 1129 | |||
| 1107 | /* Broadcom-Specific */ | 1130 | /* Broadcom-Specific */ |
| 1108 | /***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ | 1131 | /***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ |
| 1109 | enum { | 1132 | enum { |
| @@ -2158,8 +2181,8 @@ enum { | |||
| 2158 | XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */ | 2181 | XM_IS_LNK_AE = 1<<14, /* Bit 14: Link Asynchronous Event */ |
| 2159 | XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */ | 2182 | XM_IS_TX_ABORT = 1<<13, /* Bit 13: Transmit Abort, late Col. etc */ |
| 2160 | XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */ | 2183 | XM_IS_FRC_INT = 1<<12, /* Bit 12: Force INT bit set in GP */ |
| 2161 | XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */ | 2184 | XM_IS_INP_ASS = 1<<11, /* Bit 11: Input Asserted, GP bit 0 set */ |
| 2162 | XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */ | 2185 | XM_IS_LIPA_RC = 1<<10, /* Bit 10: Link Partner requests config */ |
| 2163 | XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */ | 2186 | XM_IS_RX_PAGE = 1<<9, /* Bit 9: Page Received */ |
| 2164 | XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */ | 2187 | XM_IS_TX_PAGE = 1<<8, /* Bit 8: Next Page Loaded for Transmit */ |
| 2165 | XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */ | 2188 | XM_IS_AND = 1<<7, /* Bit 7: Auto-Negotiation Done */ |
| @@ -2172,9 +2195,7 @@ enum { | |||
| 2172 | XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ | 2195 | XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ |
| 2173 | }; | 2196 | }; |
| 2174 | 2197 | ||
| 2175 | #define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | \ | 2198 | #define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR)) |
| 2176 | XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | \ | ||
| 2177 | XM_IS_RXF_OV | XM_IS_TXF_UR)) | ||
| 2178 | 2199 | ||
| 2179 | 2200 | ||
| 2180 | /* XM_HW_CFG 16 bit r/w Hardware Config Register */ | 2201 | /* XM_HW_CFG 16 bit r/w Hardware Config Register */ |
| @@ -2396,6 +2417,7 @@ struct skge_hw { | |||
| 2396 | u8 chip_rev; | 2417 | u8 chip_rev; |
| 2397 | u8 copper; | 2418 | u8 copper; |
| 2398 | u8 ports; | 2419 | u8 ports; |
| 2420 | u8 phy_type; | ||
| 2399 | 2421 | ||
| 2400 | u32 ram_size; | 2422 | u32 ram_size; |
| 2401 | u32 ram_offset; | 2423 | u32 ram_offset; |
| @@ -2422,6 +2444,7 @@ struct skge_port { | |||
| 2422 | 2444 | ||
| 2423 | struct net_device_stats net_stats; | 2445 | struct net_device_stats net_stats; |
| 2424 | 2446 | ||
| 2447 | struct work_struct link_thread; | ||
| 2425 | u8 rx_csum; | 2448 | u8 rx_csum; |
| 2426 | u8 blink_on; | 2449 | u8 blink_on; |
| 2427 | u8 flow_control; | 2450 | u8 flow_control; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 7aa7fbac8224..c660e33f43a2 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
| @@ -379,6 +379,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, | |||
| 379 | 379 | ||
| 380 | #define SMC_IRQ_FLAGS (0) | 380 | #define SMC_IRQ_FLAGS (0) |
| 381 | 381 | ||
| 382 | #elif defined(CONFIG_ARCH_VERSATILE) | ||
| 383 | |||
| 384 | #define SMC_CAN_USE_8BIT 1 | ||
| 385 | #define SMC_CAN_USE_16BIT 1 | ||
| 386 | #define SMC_CAN_USE_32BIT 1 | ||
| 387 | #define SMC_NOWAIT 1 | ||
| 388 | |||
| 389 | #define SMC_inb(a, r) readb((a) + (r)) | ||
| 390 | #define SMC_inw(a, r) readw((a) + (r)) | ||
| 391 | #define SMC_inl(a, r) readl((a) + (r)) | ||
| 392 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | ||
| 393 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | ||
| 394 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | ||
| 395 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | ||
| 396 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | ||
| 397 | |||
| 398 | #define SMC_IRQ_FLAGS (0) | ||
| 399 | |||
| 382 | #else | 400 | #else |
| 383 | 401 | ||
| 384 | #define SMC_CAN_USE_8BIT 1 | 402 | #define SMC_CAN_USE_8BIT 1 |
diff --git a/drivers/net/stnic.c b/drivers/net/stnic.c index 3fd7a4fee665..e6f90427160c 100644 --- a/drivers/net/stnic.c +++ b/drivers/net/stnic.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include <asm/system.h> | 20 | #include <asm/system.h> |
| 21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
| 22 | #include <asm/se/se.h> | 22 | #include <asm/se.h> |
| 23 | #include <asm/machvec.h> | 23 | #include <asm/machvec.h> |
| 24 | #ifdef CONFIG_SH_STANDARD_BIOS | 24 | #ifdef CONFIG_SH_STANDARD_BIOS |
| 25 | #include <asm/sh_bios.h> | 25 | #include <asm/sh_bios.h> |
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 77670741e101..feb42db10ee1 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
| @@ -1323,9 +1323,9 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = { | |||
| 1323 | .get_link = sparc_lance_get_link, | 1323 | .get_link = sparc_lance_get_link, |
| 1324 | }; | 1324 | }; |
| 1325 | 1325 | ||
| 1326 | static int __init sparc_lance_probe_one(struct sbus_dev *sdev, | 1326 | static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, |
| 1327 | struct sbus_dma *ledma, | 1327 | struct sbus_dma *ledma, |
| 1328 | struct sbus_dev *lebuffer) | 1328 | struct sbus_dev *lebuffer) |
| 1329 | { | 1329 | { |
| 1330 | static unsigned version_printed; | 1330 | static unsigned version_printed; |
| 1331 | struct net_device *dev; | 1331 | struct net_device *dev; |
| @@ -1515,7 +1515,7 @@ fail: | |||
| 1515 | } | 1515 | } |
| 1516 | 1516 | ||
| 1517 | /* On 4m, find the associated dma for the lance chip */ | 1517 | /* On 4m, find the associated dma for the lance chip */ |
| 1518 | static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | 1518 | static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev) |
| 1519 | { | 1519 | { |
| 1520 | struct sbus_dma *p; | 1520 | struct sbus_dma *p; |
| 1521 | 1521 | ||
| @@ -1533,7 +1533,7 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | |||
| 1533 | 1533 | ||
| 1534 | /* Find all the lance cards on the system and initialize them */ | 1534 | /* Find all the lance cards on the system and initialize them */ |
| 1535 | static struct sbus_dev sun4_sdev; | 1535 | static struct sbus_dev sun4_sdev; |
| 1536 | static int __init sparc_lance_init(void) | 1536 | static int __devinit sparc_lance_init(void) |
| 1537 | { | 1537 | { |
| 1538 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | 1538 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || |
| 1539 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | 1539 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { |
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index 0d66700c6ced..bfc8c3eae9a1 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c | |||
| @@ -1876,7 +1876,6 @@ static int sprintf_info(char *buffer, struct net_device *dev) | |||
| 1876 | datap[size+1]=io_word & 0xff; | 1876 | datap[size+1]=io_word & 0xff; |
| 1877 | } | 1877 | } |
| 1878 | 1878 | ||
| 1879 | |||
| 1880 | size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); | 1879 | size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); |
| 1881 | 1880 | ||
| 1882 | size += sprintf(buffer + size, | 1881 | size += sprintf(buffer + size, |
| @@ -1932,64 +1931,6 @@ static int sprintf_info(char *buffer, struct net_device *dev) | |||
| 1932 | #endif | 1931 | #endif |
| 1933 | #endif | 1932 | #endif |
| 1934 | 1933 | ||
| 1935 | #if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) | ||
| 1936 | static int streamer_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
| 1937 | { | ||
| 1938 | int i; | ||
| 1939 | struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; | ||
| 1940 | u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; | ||
| 1941 | |||
| 1942 | switch(cmd) { | ||
| 1943 | case IOCTL_SISR_MASK: | ||
| 1944 | writew(SISR_MI, streamer_mmio + SISR_MASK_SUM); | ||
| 1945 | break; | ||
| 1946 | case IOCTL_SPIN_LOCK_TEST: | ||
| 1947 | printk(KERN_INFO "spin_lock() called.\n"); | ||
| 1948 | spin_lock(&streamer_priv->streamer_lock); | ||
| 1949 | spin_unlock(&streamer_priv->streamer_lock); | ||
| 1950 | printk(KERN_INFO "spin_unlock() finished.\n"); | ||
| 1951 | break; | ||
| 1952 | case IOCTL_PRINT_BDAS: | ||
| 1953 | printk(KERN_INFO "bdas: RXBDA: %x RXLBDA: %x TX2FDA: %x TX2LFDA: %x\n", | ||
| 1954 | readw(streamer_mmio + RXBDA), | ||
| 1955 | readw(streamer_mmio + RXLBDA), | ||
| 1956 | readw(streamer_mmio + TX2FDA), | ||
| 1957 | readw(streamer_mmio + TX2LFDA)); | ||
| 1958 | break; | ||
| 1959 | case IOCTL_PRINT_REGISTERS: | ||
| 1960 | printk(KERN_INFO "registers:\n"); | ||
| 1961 | printk(KERN_INFO "SISR: %04x MISR: %04x LISR: %04x BCTL: %04x BMCTL: %04x\nmask %04x mask %04x\n", | ||
| 1962 | readw(streamer_mmio + SISR), | ||
| 1963 | readw(streamer_mmio + MISR_RUM), | ||
| 1964 | readw(streamer_mmio + LISR), | ||
| 1965 | readw(streamer_mmio + BCTL), | ||
| 1966 | readw(streamer_mmio + BMCTL_SUM), | ||
| 1967 | readw(streamer_mmio + SISR_MASK), | ||
| 1968 | readw(streamer_mmio + MISR_MASK)); | ||
| 1969 | break; | ||
| 1970 | case IOCTL_PRINT_RX_BUFS: | ||
| 1971 | printk(KERN_INFO "Print rx bufs:\n"); | ||
| 1972 | for(i=0; i<STREAMER_RX_RING_SIZE; i++) | ||
| 1973 | printk(KERN_INFO "rx_ring %d status: 0x%x\n", i, | ||
| 1974 | streamer_priv->streamer_rx_ring[i].status); | ||
| 1975 | break; | ||
| 1976 | case IOCTL_PRINT_TX_BUFS: | ||
| 1977 | printk(KERN_INFO "Print tx bufs:\n"); | ||
| 1978 | for(i=0; i<STREAMER_TX_RING_SIZE; i++) | ||
| 1979 | printk(KERN_INFO "tx_ring %d status: 0x%x\n", i, | ||
| 1980 | streamer_priv->streamer_tx_ring[i].status); | ||
| 1981 | break; | ||
| 1982 | case IOCTL_RX_CMD: | ||
| 1983 | streamer_rx(dev); | ||
| 1984 | printk(KERN_INFO "Sent rx command.\n"); | ||
| 1985 | break; | ||
| 1986 | default: | ||
| 1987 | printk(KERN_INFO "Bad ioctl!\n"); | ||
| 1988 | } | ||
| 1989 | return 0; | ||
| 1990 | } | ||
| 1991 | #endif | ||
| 1992 | |||
| 1993 | static struct pci_driver streamer_pci_driver = { | 1934 | static struct pci_driver streamer_pci_driver = { |
| 1994 | .name = "lanstreamer", | 1935 | .name = "lanstreamer", |
| 1995 | .id_table = streamer_pci_tbl, | 1936 | .id_table = streamer_pci_tbl, |
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h index 5557d8e1e22d..e7bb3494afc7 100644 --- a/drivers/net/tokenring/lanstreamer.h +++ b/drivers/net/tokenring/lanstreamer.h | |||
| @@ -62,18 +62,6 @@ | |||
| 62 | 62 | ||
| 63 | #include <linux/version.h> | 63 | #include <linux/version.h> |
| 64 | 64 | ||
| 65 | #if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) | ||
| 66 | #include <asm/ioctl.h> | ||
| 67 | #define IOCTL_PRINT_RX_BUFS SIOCDEVPRIVATE | ||
| 68 | #define IOCTL_PRINT_TX_BUFS SIOCDEVPRIVATE+1 | ||
| 69 | #define IOCTL_RX_CMD SIOCDEVPRIVATE+2 | ||
| 70 | #define IOCTL_TX_CMD SIOCDEVPRIVATE+3 | ||
| 71 | #define IOCTL_PRINT_REGISTERS SIOCDEVPRIVATE+4 | ||
| 72 | #define IOCTL_PRINT_BDAS SIOCDEVPRIVATE+5 | ||
| 73 | #define IOCTL_SPIN_LOCK_TEST SIOCDEVPRIVATE+6 | ||
| 74 | #define IOCTL_SISR_MASK SIOCDEVPRIVATE+7 | ||
| 75 | #endif | ||
| 76 | |||
| 77 | /* MAX_INTR - the maximum number of times we can loop | 65 | /* MAX_INTR - the maximum number of times we can loop |
| 78 | * inside the interrupt function before returning | 66 | * inside the interrupt function before returning |
| 79 | * control to the OS (maximum value is 256) | 67 | * control to the OS (maximum value is 256) |
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index e661d0a9cc64..fb5fa7d68888 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c | |||
| @@ -2114,6 +2114,7 @@ static struct eisa_device_id de4x5_eisa_ids[] = { | |||
| 2114 | { "DEC4250", 0 }, /* 0 is the board name index... */ | 2114 | { "DEC4250", 0 }, /* 0 is the board name index... */ |
| 2115 | { "" } | 2115 | { "" } |
| 2116 | }; | 2116 | }; |
| 2117 | MODULE_DEVICE_TABLE(eisa, de4x5_eisa_ids); | ||
| 2117 | 2118 | ||
| 2118 | static struct eisa_driver de4x5_eisa_driver = { | 2119 | static struct eisa_driver de4x5_eisa_driver = { |
| 2119 | .id_table = de4x5_eisa_ids, | 2120 | .id_table = de4x5_eisa_ids, |
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 8f6f6fd8b87d..d5c32e9caa97 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
| @@ -333,11 +333,7 @@ enum state_values { | |||
| 333 | #define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY) | 333 | #define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY) |
| 334 | #define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) | 334 | #define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY) |
| 335 | 335 | ||
| 336 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28) | ||
| 337 | #define typhoon_synchronize_irq(x) synchronize_irq() | ||
| 338 | #else | ||
| 339 | #define typhoon_synchronize_irq(x) synchronize_irq(x) | 336 | #define typhoon_synchronize_irq(x) synchronize_irq(x) |
| 340 | #endif | ||
| 341 | 337 | ||
| 342 | #if defined(NETIF_F_TSO) | 338 | #if defined(NETIF_F_TSO) |
| 343 | #define skb_tso_size(x) (skb_shinfo(x)->gso_size) | 339 | #define skb_tso_size(x) (skb_shinfo(x)->gso_size) |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 54b8e492ef97..58b7efbb0750 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
| @@ -154,7 +154,7 @@ config HDLC | |||
| 154 | If unsure, say N. | 154 | If unsure, say N. |
| 155 | 155 | ||
| 156 | config HDLC_RAW | 156 | config HDLC_RAW |
| 157 | bool "Raw HDLC support" | 157 | tristate "Raw HDLC support" |
| 158 | depends on HDLC | 158 | depends on HDLC |
| 159 | help | 159 | help |
| 160 | Generic HDLC driver supporting raw HDLC over WAN connections. | 160 | Generic HDLC driver supporting raw HDLC over WAN connections. |
| @@ -162,7 +162,7 @@ config HDLC_RAW | |||
| 162 | If unsure, say N. | 162 | If unsure, say N. |
| 163 | 163 | ||
| 164 | config HDLC_RAW_ETH | 164 | config HDLC_RAW_ETH |
| 165 | bool "Raw HDLC Ethernet device support" | 165 | tristate "Raw HDLC Ethernet device support" |
| 166 | depends on HDLC | 166 | depends on HDLC |
| 167 | help | 167 | help |
| 168 | Generic HDLC driver supporting raw HDLC Ethernet device emulation | 168 | Generic HDLC driver supporting raw HDLC Ethernet device emulation |
| @@ -173,7 +173,7 @@ config HDLC_RAW_ETH | |||
| 173 | If unsure, say N. | 173 | If unsure, say N. |
| 174 | 174 | ||
| 175 | config HDLC_CISCO | 175 | config HDLC_CISCO |
| 176 | bool "Cisco HDLC support" | 176 | tristate "Cisco HDLC support" |
| 177 | depends on HDLC | 177 | depends on HDLC |
| 178 | help | 178 | help |
| 179 | Generic HDLC driver supporting Cisco HDLC over WAN connections. | 179 | Generic HDLC driver supporting Cisco HDLC over WAN connections. |
| @@ -181,7 +181,7 @@ config HDLC_CISCO | |||
| 181 | If unsure, say N. | 181 | If unsure, say N. |
| 182 | 182 | ||
| 183 | config HDLC_FR | 183 | config HDLC_FR |
| 184 | bool "Frame Relay support" | 184 | tristate "Frame Relay support" |
| 185 | depends on HDLC | 185 | depends on HDLC |
| 186 | help | 186 | help |
| 187 | Generic HDLC driver supporting Frame Relay over WAN connections. | 187 | Generic HDLC driver supporting Frame Relay over WAN connections. |
| @@ -189,7 +189,7 @@ config HDLC_FR | |||
| 189 | If unsure, say N. | 189 | If unsure, say N. |
| 190 | 190 | ||
| 191 | config HDLC_PPP | 191 | config HDLC_PPP |
| 192 | bool "Synchronous Point-to-Point Protocol (PPP) support" | 192 | tristate "Synchronous Point-to-Point Protocol (PPP) support" |
| 193 | depends on HDLC | 193 | depends on HDLC |
| 194 | help | 194 | help |
| 195 | Generic HDLC driver supporting PPP over WAN connections. | 195 | Generic HDLC driver supporting PPP over WAN connections. |
| @@ -197,7 +197,7 @@ config HDLC_PPP | |||
| 197 | If unsure, say N. | 197 | If unsure, say N. |
| 198 | 198 | ||
| 199 | config HDLC_X25 | 199 | config HDLC_X25 |
| 200 | bool "X.25 protocol support" | 200 | tristate "X.25 protocol support" |
| 201 | depends on HDLC && (LAPB=m && HDLC=m || LAPB=y) | 201 | depends on HDLC && (LAPB=m && HDLC=m || LAPB=y) |
| 202 | help | 202 | help |
| 203 | Generic HDLC driver supporting X.25 over WAN connections. | 203 | Generic HDLC driver supporting X.25 over WAN connections. |
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 316ca6869d5e..83ec2c87ba3f 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile | |||
| @@ -9,14 +9,13 @@ cyclomx-y := cycx_main.o | |||
| 9 | cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o | 9 | cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o |
| 10 | cyclomx-objs := $(cyclomx-y) | 10 | cyclomx-objs := $(cyclomx-y) |
| 11 | 11 | ||
| 12 | hdlc-y := hdlc_generic.o | 12 | obj-$(CONFIG_HDLC) += hdlc.o |
| 13 | hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o | 13 | obj-$(CONFIG_HDLC_RAW) += hdlc_raw.o |
| 14 | hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o | 14 | obj-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o |
| 15 | hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o | 15 | obj-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o |
| 16 | hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o | 16 | obj-$(CONFIG_HDLC_FR) += hdlc_fr.o |
| 17 | hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o | 17 | obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o syncppp.o |
| 18 | hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o | 18 | obj-$(CONFIG_HDLC_X25) += hdlc_x25.o |
| 19 | hdlc-objs := $(hdlc-y) | ||
| 20 | 19 | ||
| 21 | pc300-y := pc300_drv.o | 20 | pc300-y := pc300_drv.o |
| 22 | pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o | 21 | pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o |
| @@ -38,10 +37,6 @@ obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o | |||
| 38 | obj-$(CONFIG_LAPBETHER) += lapbether.o | 37 | obj-$(CONFIG_LAPBETHER) += lapbether.o |
| 39 | obj-$(CONFIG_SBNI) += sbni.o | 38 | obj-$(CONFIG_SBNI) += sbni.o |
| 40 | obj-$(CONFIG_PC300) += pc300.o | 39 | obj-$(CONFIG_PC300) += pc300.o |
| 41 | obj-$(CONFIG_HDLC) += hdlc.o | ||
| 42 | ifeq ($(CONFIG_HDLC_PPP),y) | ||
| 43 | obj-$(CONFIG_HDLC) += syncppp.o | ||
| 44 | endif | ||
| 45 | obj-$(CONFIG_N2) += n2.o | 40 | obj-$(CONFIG_N2) += n2.o |
| 46 | obj-$(CONFIG_C101) += c101.o | 41 | obj-$(CONFIG_C101) += c101.o |
| 47 | obj-$(CONFIG_WANXL) += wanxl.o | 42 | obj-$(CONFIG_WANXL) += wanxl.o |
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc.c index 04ca1f7b6424..db354e0edbe5 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> | 4 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
| @@ -17,9 +17,9 @@ | |||
| 17 | * Use sethdlc utility to set line parameters, protocol and PVCs | 17 | * Use sethdlc utility to set line parameters, protocol and PVCs |
| 18 | * | 18 | * |
| 19 | * How does it work: | 19 | * How does it work: |
| 20 | * - proto.open(), close(), start(), stop() calls are serialized. | 20 | * - proto->open(), close(), start(), stop() calls are serialized. |
| 21 | * The order is: open, [ start, stop ... ] close ... | 21 | * The order is: open, [ start, stop ... ] close ... |
| 22 | * - proto.start() and stop() are called with spin_lock_irq held. | 22 | * - proto->start() and stop() are called with spin_lock_irq held. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| @@ -38,10 +38,12 @@ | |||
| 38 | #include <linux/hdlc.h> | 38 | #include <linux/hdlc.h> |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | static const char* version = "HDLC support module revision 1.19"; | 41 | static const char* version = "HDLC support module revision 1.20"; |
| 42 | 42 | ||
| 43 | #undef DEBUG_LINK | 43 | #undef DEBUG_LINK |
| 44 | 44 | ||
| 45 | static struct hdlc_proto *first_proto = NULL; | ||
| 46 | |||
| 45 | 47 | ||
| 46 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) | 48 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) |
| 47 | { | 49 | { |
| @@ -63,11 +65,11 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev) | |||
| 63 | static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, | 65 | static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, |
| 64 | struct packet_type *p, struct net_device *orig_dev) | 66 | struct packet_type *p, struct net_device *orig_dev) |
| 65 | { | 67 | { |
| 66 | hdlc_device *hdlc = dev_to_hdlc(dev); | 68 | struct hdlc_device_desc *desc = dev_to_desc(dev); |
| 67 | if (hdlc->proto.netif_rx) | 69 | if (desc->netif_rx) |
| 68 | return hdlc->proto.netif_rx(skb); | 70 | return desc->netif_rx(skb); |
| 69 | 71 | ||
| 70 | hdlc->stats.rx_dropped++; /* Shouldn't happen */ | 72 | desc->stats.rx_dropped++; /* Shouldn't happen */ |
| 71 | dev_kfree_skb(skb); | 73 | dev_kfree_skb(skb); |
| 72 | return NET_RX_DROP; | 74 | return NET_RX_DROP; |
| 73 | } | 75 | } |
| @@ -77,8 +79,8 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 77 | static inline void hdlc_proto_start(struct net_device *dev) | 79 | static inline void hdlc_proto_start(struct net_device *dev) |
| 78 | { | 80 | { |
| 79 | hdlc_device *hdlc = dev_to_hdlc(dev); | 81 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 80 | if (hdlc->proto.start) | 82 | if (hdlc->proto->start) |
| 81 | return hdlc->proto.start(dev); | 83 | return hdlc->proto->start(dev); |
| 82 | } | 84 | } |
| 83 | 85 | ||
| 84 | 86 | ||
| @@ -86,8 +88,8 @@ static inline void hdlc_proto_start(struct net_device *dev) | |||
| 86 | static inline void hdlc_proto_stop(struct net_device *dev) | 88 | static inline void hdlc_proto_stop(struct net_device *dev) |
| 87 | { | 89 | { |
| 88 | hdlc_device *hdlc = dev_to_hdlc(dev); | 90 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 89 | if (hdlc->proto.stop) | 91 | if (hdlc->proto->stop) |
| 90 | return hdlc->proto.stop(dev); | 92 | return hdlc->proto->stop(dev); |
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | 95 | ||
| @@ -144,15 +146,15 @@ int hdlc_open(struct net_device *dev) | |||
| 144 | { | 146 | { |
| 145 | hdlc_device *hdlc = dev_to_hdlc(dev); | 147 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 146 | #ifdef DEBUG_LINK | 148 | #ifdef DEBUG_LINK |
| 147 | printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", | 149 | printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name, |
| 148 | hdlc->carrier, hdlc->open); | 150 | hdlc->carrier, hdlc->open); |
| 149 | #endif | 151 | #endif |
| 150 | 152 | ||
| 151 | if (hdlc->proto.id == -1) | 153 | if (hdlc->proto == NULL) |
| 152 | return -ENOSYS; /* no protocol attached */ | 154 | return -ENOSYS; /* no protocol attached */ |
| 153 | 155 | ||
| 154 | if (hdlc->proto.open) { | 156 | if (hdlc->proto->open) { |
| 155 | int result = hdlc->proto.open(dev); | 157 | int result = hdlc->proto->open(dev); |
| 156 | if (result) | 158 | if (result) |
| 157 | return result; | 159 | return result; |
| 158 | } | 160 | } |
| @@ -178,7 +180,7 @@ void hdlc_close(struct net_device *dev) | |||
| 178 | { | 180 | { |
| 179 | hdlc_device *hdlc = dev_to_hdlc(dev); | 181 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 180 | #ifdef DEBUG_LINK | 182 | #ifdef DEBUG_LINK |
| 181 | printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", | 183 | printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name, |
| 182 | hdlc->carrier, hdlc->open); | 184 | hdlc->carrier, hdlc->open); |
| 183 | #endif | 185 | #endif |
| 184 | 186 | ||
| @@ -190,68 +192,34 @@ void hdlc_close(struct net_device *dev) | |||
| 190 | 192 | ||
| 191 | spin_unlock_irq(&hdlc->state_lock); | 193 | spin_unlock_irq(&hdlc->state_lock); |
| 192 | 194 | ||
| 193 | if (hdlc->proto.close) | 195 | if (hdlc->proto->close) |
| 194 | hdlc->proto.close(dev); | 196 | hdlc->proto->close(dev); |
| 195 | } | 197 | } |
| 196 | 198 | ||
| 197 | 199 | ||
| 198 | 200 | ||
| 199 | #ifndef CONFIG_HDLC_RAW | ||
| 200 | #define hdlc_raw_ioctl(dev, ifr) -ENOSYS | ||
| 201 | #endif | ||
| 202 | |||
| 203 | #ifndef CONFIG_HDLC_RAW_ETH | ||
| 204 | #define hdlc_raw_eth_ioctl(dev, ifr) -ENOSYS | ||
| 205 | #endif | ||
| 206 | |||
| 207 | #ifndef CONFIG_HDLC_PPP | ||
| 208 | #define hdlc_ppp_ioctl(dev, ifr) -ENOSYS | ||
| 209 | #endif | ||
| 210 | |||
| 211 | #ifndef CONFIG_HDLC_CISCO | ||
| 212 | #define hdlc_cisco_ioctl(dev, ifr) -ENOSYS | ||
| 213 | #endif | ||
| 214 | |||
| 215 | #ifndef CONFIG_HDLC_FR | ||
| 216 | #define hdlc_fr_ioctl(dev, ifr) -ENOSYS | ||
| 217 | #endif | ||
| 218 | |||
| 219 | #ifndef CONFIG_HDLC_X25 | ||
| 220 | #define hdlc_x25_ioctl(dev, ifr) -ENOSYS | ||
| 221 | #endif | ||
| 222 | |||
| 223 | |||
| 224 | int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 201 | int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 225 | { | 202 | { |
| 226 | hdlc_device *hdlc = dev_to_hdlc(dev); | 203 | struct hdlc_proto *proto = first_proto; |
| 227 | unsigned int proto; | 204 | int result; |
| 228 | 205 | ||
| 229 | if (cmd != SIOCWANDEV) | 206 | if (cmd != SIOCWANDEV) |
| 230 | return -EINVAL; | 207 | return -EINVAL; |
| 231 | 208 | ||
| 232 | switch(ifr->ifr_settings.type) { | 209 | if (dev_to_hdlc(dev)->proto) { |
| 233 | case IF_PROTO_HDLC: | 210 | result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); |
| 234 | case IF_PROTO_HDLC_ETH: | 211 | if (result != -EINVAL) |
| 235 | case IF_PROTO_PPP: | 212 | return result; |
| 236 | case IF_PROTO_CISCO: | ||
| 237 | case IF_PROTO_FR: | ||
| 238 | case IF_PROTO_X25: | ||
| 239 | proto = ifr->ifr_settings.type; | ||
| 240 | break; | ||
| 241 | |||
| 242 | default: | ||
| 243 | proto = hdlc->proto.id; | ||
| 244 | } | 213 | } |
| 245 | 214 | ||
| 246 | switch(proto) { | 215 | /* Not handled by currently attached protocol (if any) */ |
| 247 | case IF_PROTO_HDLC: return hdlc_raw_ioctl(dev, ifr); | 216 | |
| 248 | case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(dev, ifr); | 217 | while (proto) { |
| 249 | case IF_PROTO_PPP: return hdlc_ppp_ioctl(dev, ifr); | 218 | if ((result = proto->ioctl(dev, ifr)) != -EINVAL) |
| 250 | case IF_PROTO_CISCO: return hdlc_cisco_ioctl(dev, ifr); | 219 | return result; |
| 251 | case IF_PROTO_FR: return hdlc_fr_ioctl(dev, ifr); | 220 | proto = proto->next; |
| 252 | case IF_PROTO_X25: return hdlc_x25_ioctl(dev, ifr); | ||
| 253 | default: return -EINVAL; | ||
| 254 | } | 221 | } |
| 222 | return -EINVAL; | ||
| 255 | } | 223 | } |
| 256 | 224 | ||
| 257 | void hdlc_setup(struct net_device *dev) | 225 | void hdlc_setup(struct net_device *dev) |
| @@ -267,8 +235,6 @@ void hdlc_setup(struct net_device *dev) | |||
| 267 | 235 | ||
| 268 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | 236 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; |
| 269 | 237 | ||
| 270 | hdlc->proto.id = -1; | ||
| 271 | hdlc->proto.detach = NULL; | ||
| 272 | hdlc->carrier = 1; | 238 | hdlc->carrier = 1; |
| 273 | hdlc->open = 0; | 239 | hdlc->open = 0; |
| 274 | spin_lock_init(&hdlc->state_lock); | 240 | spin_lock_init(&hdlc->state_lock); |
| @@ -277,7 +243,8 @@ void hdlc_setup(struct net_device *dev) | |||
| 277 | struct net_device *alloc_hdlcdev(void *priv) | 243 | struct net_device *alloc_hdlcdev(void *priv) |
| 278 | { | 244 | { |
| 279 | struct net_device *dev; | 245 | struct net_device *dev; |
| 280 | dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup); | 246 | dev = alloc_netdev(sizeof(struct hdlc_device_desc) + |
| 247 | sizeof(hdlc_device), "hdlc%d", hdlc_setup); | ||
| 281 | if (dev) | 248 | if (dev) |
| 282 | dev_to_hdlc(dev)->priv = priv; | 249 | dev_to_hdlc(dev)->priv = priv; |
| 283 | return dev; | 250 | return dev; |
| @@ -286,13 +253,71 @@ struct net_device *alloc_hdlcdev(void *priv) | |||
| 286 | void unregister_hdlc_device(struct net_device *dev) | 253 | void unregister_hdlc_device(struct net_device *dev) |
| 287 | { | 254 | { |
| 288 | rtnl_lock(); | 255 | rtnl_lock(); |
| 289 | hdlc_proto_detach(dev_to_hdlc(dev)); | ||
| 290 | unregister_netdevice(dev); | 256 | unregister_netdevice(dev); |
| 257 | detach_hdlc_protocol(dev); | ||
| 291 | rtnl_unlock(); | 258 | rtnl_unlock(); |
| 292 | } | 259 | } |
| 293 | 260 | ||
| 294 | 261 | ||
| 295 | 262 | ||
| 263 | int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, | ||
| 264 | int (*rx)(struct sk_buff *skb), size_t size) | ||
| 265 | { | ||
| 266 | detach_hdlc_protocol(dev); | ||
| 267 | |||
| 268 | if (!try_module_get(proto->module)) | ||
| 269 | return -ENOSYS; | ||
| 270 | |||
| 271 | if (size) | ||
| 272 | if ((dev_to_hdlc(dev)->state = kmalloc(size, | ||
| 273 | GFP_KERNEL)) == NULL) { | ||
| 274 | printk(KERN_WARNING "Memory squeeze on" | ||
| 275 | " hdlc_proto_attach()\n"); | ||
| 276 | module_put(proto->module); | ||
| 277 | return -ENOBUFS; | ||
| 278 | } | ||
| 279 | dev_to_hdlc(dev)->proto = proto; | ||
| 280 | dev_to_desc(dev)->netif_rx = rx; | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | |||
| 285 | void detach_hdlc_protocol(struct net_device *dev) | ||
| 286 | { | ||
| 287 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 288 | |||
| 289 | if (hdlc->proto) { | ||
| 290 | if (hdlc->proto->detach) | ||
| 291 | hdlc->proto->detach(dev); | ||
| 292 | module_put(hdlc->proto->module); | ||
| 293 | hdlc->proto = NULL; | ||
| 294 | } | ||
| 295 | kfree(hdlc->state); | ||
| 296 | hdlc->state = NULL; | ||
| 297 | } | ||
| 298 | |||
| 299 | |||
| 300 | void register_hdlc_protocol(struct hdlc_proto *proto) | ||
| 301 | { | ||
| 302 | proto->next = first_proto; | ||
| 303 | first_proto = proto; | ||
| 304 | } | ||
| 305 | |||
| 306 | |||
| 307 | void unregister_hdlc_protocol(struct hdlc_proto *proto) | ||
| 308 | { | ||
| 309 | struct hdlc_proto **p = &first_proto; | ||
| 310 | while (*p) { | ||
| 311 | if (*p == proto) { | ||
| 312 | *p = proto->next; | ||
| 313 | return; | ||
| 314 | } | ||
| 315 | p = &((*p)->next); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | |||
| 320 | |||
| 296 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | 321 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); |
| 297 | MODULE_DESCRIPTION("HDLC support module"); | 322 | MODULE_DESCRIPTION("HDLC support module"); |
| 298 | MODULE_LICENSE("GPL v2"); | 323 | MODULE_LICENSE("GPL v2"); |
| @@ -303,6 +328,10 @@ EXPORT_SYMBOL(hdlc_ioctl); | |||
| 303 | EXPORT_SYMBOL(hdlc_setup); | 328 | EXPORT_SYMBOL(hdlc_setup); |
| 304 | EXPORT_SYMBOL(alloc_hdlcdev); | 329 | EXPORT_SYMBOL(alloc_hdlcdev); |
| 305 | EXPORT_SYMBOL(unregister_hdlc_device); | 330 | EXPORT_SYMBOL(unregister_hdlc_device); |
| 331 | EXPORT_SYMBOL(register_hdlc_protocol); | ||
| 332 | EXPORT_SYMBOL(unregister_hdlc_protocol); | ||
| 333 | EXPORT_SYMBOL(attach_hdlc_protocol); | ||
| 334 | EXPORT_SYMBOL(detach_hdlc_protocol); | ||
| 306 | 335 | ||
| 307 | static struct packet_type hdlc_packet_type = { | 336 | static struct packet_type hdlc_packet_type = { |
| 308 | .type = __constant_htons(ETH_P_HDLC), | 337 | .type = __constant_htons(ETH_P_HDLC), |
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index f289daba0c7b..7ec2b2f9b7ee 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * Cisco HDLC support | 3 | * Cisco HDLC support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 2000 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -34,17 +34,56 @@ | |||
| 34 | #define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ | 34 | #define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | struct hdlc_header { | ||
| 38 | u8 address; | ||
| 39 | u8 control; | ||
| 40 | u16 protocol; | ||
| 41 | }__attribute__ ((packed)); | ||
| 42 | |||
| 43 | |||
| 44 | struct cisco_packet { | ||
| 45 | u32 type; /* code */ | ||
| 46 | u32 par1; | ||
| 47 | u32 par2; | ||
| 48 | u16 rel; /* reliability */ | ||
| 49 | u32 time; | ||
| 50 | }__attribute__ ((packed)); | ||
| 51 | #define CISCO_PACKET_LEN 18 | ||
| 52 | #define CISCO_BIG_PACKET_LEN 20 | ||
| 53 | |||
| 54 | |||
| 55 | struct cisco_state { | ||
| 56 | cisco_proto settings; | ||
| 57 | |||
| 58 | struct timer_list timer; | ||
| 59 | unsigned long last_poll; | ||
| 60 | int up; | ||
| 61 | int request_sent; | ||
| 62 | u32 txseq; /* TX sequence number */ | ||
| 63 | u32 rxseq; /* RX sequence number */ | ||
| 64 | }; | ||
| 65 | |||
| 66 | |||
| 67 | static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 68 | |||
| 69 | |||
| 70 | static inline struct cisco_state * state(hdlc_device *hdlc) | ||
| 71 | { | ||
| 72 | return(struct cisco_state *)(hdlc->state); | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 37 | static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, | 76 | static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, |
| 38 | u16 type, void *daddr, void *saddr, | 77 | u16 type, void *daddr, void *saddr, |
| 39 | unsigned int len) | 78 | unsigned int len) |
| 40 | { | 79 | { |
| 41 | hdlc_header *data; | 80 | struct hdlc_header *data; |
| 42 | #ifdef DEBUG_HARD_HEADER | 81 | #ifdef DEBUG_HARD_HEADER |
| 43 | printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); | 82 | printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); |
| 44 | #endif | 83 | #endif |
| 45 | 84 | ||
| 46 | skb_push(skb, sizeof(hdlc_header)); | 85 | skb_push(skb, sizeof(struct hdlc_header)); |
| 47 | data = (hdlc_header*)skb->data; | 86 | data = (struct hdlc_header*)skb->data; |
| 48 | if (type == CISCO_KEEPALIVE) | 87 | if (type == CISCO_KEEPALIVE) |
| 49 | data->address = CISCO_MULTICAST; | 88 | data->address = CISCO_MULTICAST; |
| 50 | else | 89 | else |
| @@ -52,7 +91,7 @@ static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
| 52 | data->control = 0; | 91 | data->control = 0; |
| 53 | data->protocol = htons(type); | 92 | data->protocol = htons(type); |
| 54 | 93 | ||
| 55 | return sizeof(hdlc_header); | 94 | return sizeof(struct hdlc_header); |
| 56 | } | 95 | } |
| 57 | 96 | ||
| 58 | 97 | ||
| @@ -61,9 +100,10 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, | |||
| 61 | u32 par1, u32 par2) | 100 | u32 par1, u32 par2) |
| 62 | { | 101 | { |
| 63 | struct sk_buff *skb; | 102 | struct sk_buff *skb; |
| 64 | cisco_packet *data; | 103 | struct cisco_packet *data; |
| 65 | 104 | ||
| 66 | skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); | 105 | skb = dev_alloc_skb(sizeof(struct hdlc_header) + |
| 106 | sizeof(struct cisco_packet)); | ||
| 67 | if (!skb) { | 107 | if (!skb) { |
| 68 | printk(KERN_WARNING | 108 | printk(KERN_WARNING |
| 69 | "%s: Memory squeeze on cisco_keepalive_send()\n", | 109 | "%s: Memory squeeze on cisco_keepalive_send()\n", |
| @@ -72,7 +112,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, | |||
| 72 | } | 112 | } |
| 73 | skb_reserve(skb, 4); | 113 | skb_reserve(skb, 4); |
| 74 | cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); | 114 | cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); |
| 75 | data = (cisco_packet*)(skb->data + 4); | 115 | data = (struct cisco_packet*)(skb->data + 4); |
| 76 | 116 | ||
| 77 | data->type = htonl(type); | 117 | data->type = htonl(type); |
| 78 | data->par1 = htonl(par1); | 118 | data->par1 = htonl(par1); |
| @@ -81,7 +121,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, | |||
| 81 | /* we will need do_div here if 1000 % HZ != 0 */ | 121 | /* we will need do_div here if 1000 % HZ != 0 */ |
| 82 | data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); | 122 | data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); |
| 83 | 123 | ||
| 84 | skb_put(skb, sizeof(cisco_packet)); | 124 | skb_put(skb, sizeof(struct cisco_packet)); |
| 85 | skb->priority = TC_PRIO_CONTROL; | 125 | skb->priority = TC_PRIO_CONTROL; |
| 86 | skb->dev = dev; | 126 | skb->dev = dev; |
| 87 | skb->nh.raw = skb->data; | 127 | skb->nh.raw = skb->data; |
| @@ -93,9 +133,9 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, | |||
| 93 | 133 | ||
| 94 | static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) | 134 | static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) |
| 95 | { | 135 | { |
| 96 | hdlc_header *data = (hdlc_header*)skb->data; | 136 | struct hdlc_header *data = (struct hdlc_header*)skb->data; |
| 97 | 137 | ||
| 98 | if (skb->len < sizeof(hdlc_header)) | 138 | if (skb->len < sizeof(struct hdlc_header)) |
| 99 | return __constant_htons(ETH_P_HDLC); | 139 | return __constant_htons(ETH_P_HDLC); |
| 100 | 140 | ||
| 101 | if (data->address != CISCO_MULTICAST && | 141 | if (data->address != CISCO_MULTICAST && |
| @@ -106,7 +146,7 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 106 | case __constant_htons(ETH_P_IP): | 146 | case __constant_htons(ETH_P_IP): |
| 107 | case __constant_htons(ETH_P_IPX): | 147 | case __constant_htons(ETH_P_IPX): |
| 108 | case __constant_htons(ETH_P_IPV6): | 148 | case __constant_htons(ETH_P_IPV6): |
| 109 | skb_pull(skb, sizeof(hdlc_header)); | 149 | skb_pull(skb, sizeof(struct hdlc_header)); |
| 110 | return data->protocol; | 150 | return data->protocol; |
| 111 | default: | 151 | default: |
| 112 | return __constant_htons(ETH_P_HDLC); | 152 | return __constant_htons(ETH_P_HDLC); |
| @@ -118,12 +158,12 @@ static int cisco_rx(struct sk_buff *skb) | |||
| 118 | { | 158 | { |
| 119 | struct net_device *dev = skb->dev; | 159 | struct net_device *dev = skb->dev; |
| 120 | hdlc_device *hdlc = dev_to_hdlc(dev); | 160 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 121 | hdlc_header *data = (hdlc_header*)skb->data; | 161 | struct hdlc_header *data = (struct hdlc_header*)skb->data; |
| 122 | cisco_packet *cisco_data; | 162 | struct cisco_packet *cisco_data; |
| 123 | struct in_device *in_dev; | 163 | struct in_device *in_dev; |
| 124 | u32 addr, mask; | 164 | u32 addr, mask; |
| 125 | 165 | ||
| 126 | if (skb->len < sizeof(hdlc_header)) | 166 | if (skb->len < sizeof(struct hdlc_header)) |
| 127 | goto rx_error; | 167 | goto rx_error; |
| 128 | 168 | ||
| 129 | if (data->address != CISCO_MULTICAST && | 169 | if (data->address != CISCO_MULTICAST && |
| @@ -137,15 +177,17 @@ static int cisco_rx(struct sk_buff *skb) | |||
| 137 | return NET_RX_SUCCESS; | 177 | return NET_RX_SUCCESS; |
| 138 | 178 | ||
| 139 | case CISCO_KEEPALIVE: | 179 | case CISCO_KEEPALIVE: |
| 140 | if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && | 180 | if ((skb->len != sizeof(struct hdlc_header) + |
| 141 | skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { | 181 | CISCO_PACKET_LEN) && |
| 142 | printk(KERN_INFO "%s: Invalid length of Cisco " | 182 | (skb->len != sizeof(struct hdlc_header) + |
| 143 | "control packet (%d bytes)\n", | 183 | CISCO_BIG_PACKET_LEN)) { |
| 144 | dev->name, skb->len); | 184 | printk(KERN_INFO "%s: Invalid length of Cisco control" |
| 185 | " packet (%d bytes)\n", dev->name, skb->len); | ||
| 145 | goto rx_error; | 186 | goto rx_error; |
| 146 | } | 187 | } |
| 147 | 188 | ||
| 148 | cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); | 189 | cisco_data = (struct cisco_packet*)(skb->data + sizeof |
| 190 | (struct hdlc_header)); | ||
| 149 | 191 | ||
| 150 | switch(ntohl (cisco_data->type)) { | 192 | switch(ntohl (cisco_data->type)) { |
| 151 | case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ | 193 | case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ |
| @@ -178,11 +220,11 @@ static int cisco_rx(struct sk_buff *skb) | |||
| 178 | goto rx_error; | 220 | goto rx_error; |
| 179 | 221 | ||
| 180 | case CISCO_KEEPALIVE_REQ: | 222 | case CISCO_KEEPALIVE_REQ: |
| 181 | hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); | 223 | state(hdlc)->rxseq = ntohl(cisco_data->par1); |
| 182 | if (hdlc->state.cisco.request_sent && | 224 | if (state(hdlc)->request_sent && |
| 183 | ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { | 225 | ntohl(cisco_data->par2) == state(hdlc)->txseq) { |
| 184 | hdlc->state.cisco.last_poll = jiffies; | 226 | state(hdlc)->last_poll = jiffies; |
| 185 | if (!hdlc->state.cisco.up) { | 227 | if (!state(hdlc)->up) { |
| 186 | u32 sec, min, hrs, days; | 228 | u32 sec, min, hrs, days; |
| 187 | sec = ntohl(cisco_data->time) / 1000; | 229 | sec = ntohl(cisco_data->time) / 1000; |
| 188 | min = sec / 60; sec -= min * 60; | 230 | min = sec / 60; sec -= min * 60; |
| @@ -193,7 +235,7 @@ static int cisco_rx(struct sk_buff *skb) | |||
| 193 | dev->name, days, hrs, | 235 | dev->name, days, hrs, |
| 194 | min, sec); | 236 | min, sec); |
| 195 | netif_dormant_off(dev); | 237 | netif_dormant_off(dev); |
| 196 | hdlc->state.cisco.up = 1; | 238 | state(hdlc)->up = 1; |
| 197 | } | 239 | } |
| 198 | } | 240 | } |
| 199 | 241 | ||
| @@ -208,7 +250,7 @@ static int cisco_rx(struct sk_buff *skb) | |||
| 208 | return NET_RX_DROP; | 250 | return NET_RX_DROP; |
| 209 | 251 | ||
| 210 | rx_error: | 252 | rx_error: |
| 211 | hdlc->stats.rx_errors++; /* Mark error */ | 253 | dev_to_desc(dev)->stats.rx_errors++; /* Mark error */ |
| 212 | dev_kfree_skb_any(skb); | 254 | dev_kfree_skb_any(skb); |
| 213 | return NET_RX_DROP; | 255 | return NET_RX_DROP; |
| 214 | } | 256 | } |
| @@ -220,23 +262,22 @@ static void cisco_timer(unsigned long arg) | |||
| 220 | struct net_device *dev = (struct net_device *)arg; | 262 | struct net_device *dev = (struct net_device *)arg; |
| 221 | hdlc_device *hdlc = dev_to_hdlc(dev); | 263 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 222 | 264 | ||
| 223 | if (hdlc->state.cisco.up && | 265 | if (state(hdlc)->up && |
| 224 | time_after(jiffies, hdlc->state.cisco.last_poll + | 266 | time_after(jiffies, state(hdlc)->last_poll + |
| 225 | hdlc->state.cisco.settings.timeout * HZ)) { | 267 | state(hdlc)->settings.timeout * HZ)) { |
| 226 | hdlc->state.cisco.up = 0; | 268 | state(hdlc)->up = 0; |
| 227 | printk(KERN_INFO "%s: Link down\n", dev->name); | 269 | printk(KERN_INFO "%s: Link down\n", dev->name); |
| 228 | netif_dormant_on(dev); | 270 | netif_dormant_on(dev); |
| 229 | } | 271 | } |
| 230 | 272 | ||
| 231 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, | 273 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++state(hdlc)->txseq, |
| 232 | ++hdlc->state.cisco.txseq, | 274 | state(hdlc)->rxseq); |
| 233 | hdlc->state.cisco.rxseq); | 275 | state(hdlc)->request_sent = 1; |
| 234 | hdlc->state.cisco.request_sent = 1; | 276 | state(hdlc)->timer.expires = jiffies + |
| 235 | hdlc->state.cisco.timer.expires = jiffies + | 277 | state(hdlc)->settings.interval * HZ; |
| 236 | hdlc->state.cisco.settings.interval * HZ; | 278 | state(hdlc)->timer.function = cisco_timer; |
| 237 | hdlc->state.cisco.timer.function = cisco_timer; | 279 | state(hdlc)->timer.data = arg; |
| 238 | hdlc->state.cisco.timer.data = arg; | 280 | add_timer(&state(hdlc)->timer); |
| 239 | add_timer(&hdlc->state.cisco.timer); | ||
| 240 | } | 281 | } |
| 241 | 282 | ||
| 242 | 283 | ||
| @@ -244,15 +285,15 @@ static void cisco_timer(unsigned long arg) | |||
| 244 | static void cisco_start(struct net_device *dev) | 285 | static void cisco_start(struct net_device *dev) |
| 245 | { | 286 | { |
| 246 | hdlc_device *hdlc = dev_to_hdlc(dev); | 287 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 247 | hdlc->state.cisco.up = 0; | 288 | state(hdlc)->up = 0; |
| 248 | hdlc->state.cisco.request_sent = 0; | 289 | state(hdlc)->request_sent = 0; |
| 249 | hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; | 290 | state(hdlc)->txseq = state(hdlc)->rxseq = 0; |
| 250 | 291 | ||
| 251 | init_timer(&hdlc->state.cisco.timer); | 292 | init_timer(&state(hdlc)->timer); |
| 252 | hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ | 293 | state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/ |
| 253 | hdlc->state.cisco.timer.function = cisco_timer; | 294 | state(hdlc)->timer.function = cisco_timer; |
| 254 | hdlc->state.cisco.timer.data = (unsigned long)dev; | 295 | state(hdlc)->timer.data = (unsigned long)dev; |
| 255 | add_timer(&hdlc->state.cisco.timer); | 296 | add_timer(&state(hdlc)->timer); |
| 256 | } | 297 | } |
| 257 | 298 | ||
| 258 | 299 | ||
| @@ -260,15 +301,24 @@ static void cisco_start(struct net_device *dev) | |||
| 260 | static void cisco_stop(struct net_device *dev) | 301 | static void cisco_stop(struct net_device *dev) |
| 261 | { | 302 | { |
| 262 | hdlc_device *hdlc = dev_to_hdlc(dev); | 303 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 263 | del_timer_sync(&hdlc->state.cisco.timer); | 304 | del_timer_sync(&state(hdlc)->timer); |
| 264 | netif_dormant_on(dev); | 305 | netif_dormant_on(dev); |
| 265 | hdlc->state.cisco.up = 0; | 306 | state(hdlc)->up = 0; |
| 266 | hdlc->state.cisco.request_sent = 0; | 307 | state(hdlc)->request_sent = 0; |
| 267 | } | 308 | } |
| 268 | 309 | ||
| 269 | 310 | ||
| 270 | 311 | ||
| 271 | int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | 312 | static struct hdlc_proto proto = { |
| 313 | .start = cisco_start, | ||
| 314 | .stop = cisco_stop, | ||
| 315 | .type_trans = cisco_type_trans, | ||
| 316 | .ioctl = cisco_ioctl, | ||
| 317 | .module = THIS_MODULE, | ||
| 318 | }; | ||
| 319 | |||
| 320 | |||
| 321 | static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
| 272 | { | 322 | { |
| 273 | cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; | 323 | cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; |
| 274 | const size_t size = sizeof(cisco_proto); | 324 | const size_t size = sizeof(cisco_proto); |
| @@ -278,12 +328,14 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 278 | 328 | ||
| 279 | switch (ifr->ifr_settings.type) { | 329 | switch (ifr->ifr_settings.type) { |
| 280 | case IF_GET_PROTO: | 330 | case IF_GET_PROTO: |
| 331 | if (dev_to_hdlc(dev)->proto != &proto) | ||
| 332 | return -EINVAL; | ||
| 281 | ifr->ifr_settings.type = IF_PROTO_CISCO; | 333 | ifr->ifr_settings.type = IF_PROTO_CISCO; |
| 282 | if (ifr->ifr_settings.size < size) { | 334 | if (ifr->ifr_settings.size < size) { |
| 283 | ifr->ifr_settings.size = size; /* data size wanted */ | 335 | ifr->ifr_settings.size = size; /* data size wanted */ |
| 284 | return -ENOBUFS; | 336 | return -ENOBUFS; |
| 285 | } | 337 | } |
| 286 | if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) | 338 | if (copy_to_user(cisco_s, &state(hdlc)->settings, size)) |
| 287 | return -EFAULT; | 339 | return -EFAULT; |
| 288 | return 0; | 340 | return 0; |
| 289 | 341 | ||
| @@ -302,19 +354,15 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 302 | return -EINVAL; | 354 | return -EINVAL; |
| 303 | 355 | ||
| 304 | result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); | 356 | result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); |
| 305 | |||
| 306 | if (result) | 357 | if (result) |
| 307 | return result; | 358 | return result; |
| 308 | 359 | ||
| 309 | hdlc_proto_detach(hdlc); | 360 | result = attach_hdlc_protocol(dev, &proto, cisco_rx, |
| 310 | memcpy(&hdlc->state.cisco.settings, &new_settings, size); | 361 | sizeof(struct cisco_state)); |
| 311 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 362 | if (result) |
| 363 | return result; | ||
| 312 | 364 | ||
| 313 | hdlc->proto.start = cisco_start; | 365 | memcpy(&state(hdlc)->settings, &new_settings, size); |
| 314 | hdlc->proto.stop = cisco_stop; | ||
| 315 | hdlc->proto.netif_rx = cisco_rx; | ||
| 316 | hdlc->proto.type_trans = cisco_type_trans; | ||
| 317 | hdlc->proto.id = IF_PROTO_CISCO; | ||
| 318 | dev->hard_start_xmit = hdlc->xmit; | 366 | dev->hard_start_xmit = hdlc->xmit; |
| 319 | dev->hard_header = cisco_hard_header; | 367 | dev->hard_header = cisco_hard_header; |
| 320 | dev->hard_header_cache = NULL; | 368 | dev->hard_header_cache = NULL; |
| @@ -327,3 +375,25 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 327 | 375 | ||
| 328 | return -EINVAL; | 376 | return -EINVAL; |
| 329 | } | 377 | } |
| 378 | |||
| 379 | |||
| 380 | static int __init mod_init(void) | ||
| 381 | { | ||
| 382 | register_hdlc_protocol(&proto); | ||
| 383 | return 0; | ||
| 384 | } | ||
| 385 | |||
| 386 | |||
| 387 | |||
| 388 | static void __exit mod_exit(void) | ||
| 389 | { | ||
| 390 | unregister_hdlc_protocol(&proto); | ||
| 391 | } | ||
| 392 | |||
| 393 | |||
| 394 | module_init(mod_init); | ||
| 395 | module_exit(mod_exit); | ||
| 396 | |||
| 397 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 398 | MODULE_DESCRIPTION("Cisco HDLC protocol support for generic HDLC"); | ||
| 399 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 7bb737bbdeb9..b45ab680d2d6 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * Frame Relay support | 3 | * Frame Relay support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -52,6 +52,8 @@ | |||
| 52 | #undef DEBUG_PKT | 52 | #undef DEBUG_PKT |
| 53 | #undef DEBUG_ECN | 53 | #undef DEBUG_ECN |
| 54 | #undef DEBUG_LINK | 54 | #undef DEBUG_LINK |
| 55 | #undef DEBUG_PROTO | ||
| 56 | #undef DEBUG_PVC | ||
| 55 | 57 | ||
| 56 | #define FR_UI 0x03 | 58 | #define FR_UI 0x03 |
| 57 | #define FR_PAD 0x00 | 59 | #define FR_PAD 0x00 |
| @@ -115,13 +117,53 @@ typedef struct { | |||
| 115 | }__attribute__ ((packed)) fr_hdr; | 117 | }__attribute__ ((packed)) fr_hdr; |
| 116 | 118 | ||
| 117 | 119 | ||
| 120 | typedef struct pvc_device_struct { | ||
| 121 | struct net_device *frad; | ||
| 122 | struct net_device *main; | ||
| 123 | struct net_device *ether; /* bridged Ethernet interface */ | ||
| 124 | struct pvc_device_struct *next; /* Sorted in ascending DLCI order */ | ||
| 125 | int dlci; | ||
| 126 | int open_count; | ||
| 127 | |||
| 128 | struct { | ||
| 129 | unsigned int new: 1; | ||
| 130 | unsigned int active: 1; | ||
| 131 | unsigned int exist: 1; | ||
| 132 | unsigned int deleted: 1; | ||
| 133 | unsigned int fecn: 1; | ||
| 134 | unsigned int becn: 1; | ||
| 135 | unsigned int bandwidth; /* Cisco LMI reporting only */ | ||
| 136 | }state; | ||
| 137 | }pvc_device; | ||
| 138 | |||
| 139 | |||
| 140 | struct frad_state { | ||
| 141 | fr_proto settings; | ||
| 142 | pvc_device *first_pvc; | ||
| 143 | int dce_pvc_count; | ||
| 144 | |||
| 145 | struct timer_list timer; | ||
| 146 | unsigned long last_poll; | ||
| 147 | int reliable; | ||
| 148 | int dce_changed; | ||
| 149 | int request; | ||
| 150 | int fullrep_sent; | ||
| 151 | u32 last_errors; /* last errors bit list */ | ||
| 152 | u8 n391cnt; | ||
| 153 | u8 txseq; /* TX sequence number */ | ||
| 154 | u8 rxseq; /* RX sequence number */ | ||
| 155 | }; | ||
| 156 | |||
| 157 | |||
| 158 | static int fr_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 159 | |||
| 160 | |||
| 118 | static inline u16 q922_to_dlci(u8 *hdr) | 161 | static inline u16 q922_to_dlci(u8 *hdr) |
| 119 | { | 162 | { |
| 120 | return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); | 163 | return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); |
| 121 | } | 164 | } |
| 122 | 165 | ||
| 123 | 166 | ||
| 124 | |||
| 125 | static inline void dlci_to_q922(u8 *hdr, u16 dlci) | 167 | static inline void dlci_to_q922(u8 *hdr, u16 dlci) |
| 126 | { | 168 | { |
| 127 | hdr[0] = (dlci >> 2) & 0xFC; | 169 | hdr[0] = (dlci >> 2) & 0xFC; |
| @@ -129,10 +171,21 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci) | |||
| 129 | } | 171 | } |
| 130 | 172 | ||
| 131 | 173 | ||
| 174 | static inline struct frad_state * state(hdlc_device *hdlc) | ||
| 175 | { | ||
| 176 | return(struct frad_state *)(hdlc->state); | ||
| 177 | } | ||
| 178 | |||
| 179 | |||
| 180 | static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) | ||
| 181 | { | ||
| 182 | return dev->priv; | ||
| 183 | } | ||
| 184 | |||
| 132 | 185 | ||
| 133 | static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) | 186 | static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) |
| 134 | { | 187 | { |
| 135 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 188 | pvc_device *pvc = state(hdlc)->first_pvc; |
| 136 | 189 | ||
| 137 | while (pvc) { | 190 | while (pvc) { |
| 138 | if (pvc->dlci == dlci) | 191 | if (pvc->dlci == dlci) |
| @@ -146,10 +199,10 @@ static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) | |||
| 146 | } | 199 | } |
| 147 | 200 | ||
| 148 | 201 | ||
| 149 | static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) | 202 | static pvc_device* add_pvc(struct net_device *dev, u16 dlci) |
| 150 | { | 203 | { |
| 151 | hdlc_device *hdlc = dev_to_hdlc(dev); | 204 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 152 | pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; | 205 | pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc; |
| 153 | 206 | ||
| 154 | while (*pvc_p) { | 207 | while (*pvc_p) { |
| 155 | if ((*pvc_p)->dlci == dlci) | 208 | if ((*pvc_p)->dlci == dlci) |
| @@ -160,12 +213,15 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) | |||
| 160 | } | 213 | } |
| 161 | 214 | ||
| 162 | pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); | 215 | pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); |
| 216 | #ifdef DEBUG_PVC | ||
| 217 | printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev); | ||
| 218 | #endif | ||
| 163 | if (!pvc) | 219 | if (!pvc) |
| 164 | return NULL; | 220 | return NULL; |
| 165 | 221 | ||
| 166 | memset(pvc, 0, sizeof(pvc_device)); | 222 | memset(pvc, 0, sizeof(pvc_device)); |
| 167 | pvc->dlci = dlci; | 223 | pvc->dlci = dlci; |
| 168 | pvc->master = dev; | 224 | pvc->frad = dev; |
| 169 | pvc->next = *pvc_p; /* Put it in the chain */ | 225 | pvc->next = *pvc_p; /* Put it in the chain */ |
| 170 | *pvc_p = pvc; | 226 | *pvc_p = pvc; |
| 171 | return pvc; | 227 | return pvc; |
| @@ -174,7 +230,7 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) | |||
| 174 | 230 | ||
| 175 | static inline int pvc_is_used(pvc_device *pvc) | 231 | static inline int pvc_is_used(pvc_device *pvc) |
| 176 | { | 232 | { |
| 177 | return pvc->main != NULL || pvc->ether != NULL; | 233 | return pvc->main || pvc->ether; |
| 178 | } | 234 | } |
| 179 | 235 | ||
| 180 | 236 | ||
| @@ -200,11 +256,14 @@ static inline void pvc_carrier(int on, pvc_device *pvc) | |||
| 200 | 256 | ||
| 201 | static inline void delete_unused_pvcs(hdlc_device *hdlc) | 257 | static inline void delete_unused_pvcs(hdlc_device *hdlc) |
| 202 | { | 258 | { |
| 203 | pvc_device **pvc_p = &hdlc->state.fr.first_pvc; | 259 | pvc_device **pvc_p = &state(hdlc)->first_pvc; |
| 204 | 260 | ||
| 205 | while (*pvc_p) { | 261 | while (*pvc_p) { |
| 206 | if (!pvc_is_used(*pvc_p)) { | 262 | if (!pvc_is_used(*pvc_p)) { |
| 207 | pvc_device *pvc = *pvc_p; | 263 | pvc_device *pvc = *pvc_p; |
| 264 | #ifdef DEBUG_PVC | ||
| 265 | printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc); | ||
| 266 | #endif | ||
| 208 | *pvc_p = pvc->next; | 267 | *pvc_p = pvc->next; |
| 209 | kfree(pvc); | 268 | kfree(pvc); |
| 210 | continue; | 269 | continue; |
| @@ -295,16 +354,16 @@ static int pvc_open(struct net_device *dev) | |||
| 295 | { | 354 | { |
| 296 | pvc_device *pvc = dev_to_pvc(dev); | 355 | pvc_device *pvc = dev_to_pvc(dev); |
| 297 | 356 | ||
| 298 | if ((pvc->master->flags & IFF_UP) == 0) | 357 | if ((pvc->frad->flags & IFF_UP) == 0) |
| 299 | return -EIO; /* Master must be UP in order to activate PVC */ | 358 | return -EIO; /* Frad must be UP in order to activate PVC */ |
| 300 | 359 | ||
| 301 | if (pvc->open_count++ == 0) { | 360 | if (pvc->open_count++ == 0) { |
| 302 | hdlc_device *hdlc = dev_to_hdlc(pvc->master); | 361 | hdlc_device *hdlc = dev_to_hdlc(pvc->frad); |
| 303 | if (hdlc->state.fr.settings.lmi == LMI_NONE) | 362 | if (state(hdlc)->settings.lmi == LMI_NONE) |
| 304 | pvc->state.active = netif_carrier_ok(pvc->master); | 363 | pvc->state.active = netif_carrier_ok(pvc->frad); |
| 305 | 364 | ||
| 306 | pvc_carrier(pvc->state.active, pvc); | 365 | pvc_carrier(pvc->state.active, pvc); |
| 307 | hdlc->state.fr.dce_changed = 1; | 366 | state(hdlc)->dce_changed = 1; |
| 308 | } | 367 | } |
| 309 | return 0; | 368 | return 0; |
| 310 | } | 369 | } |
| @@ -316,12 +375,12 @@ static int pvc_close(struct net_device *dev) | |||
| 316 | pvc_device *pvc = dev_to_pvc(dev); | 375 | pvc_device *pvc = dev_to_pvc(dev); |
| 317 | 376 | ||
| 318 | if (--pvc->open_count == 0) { | 377 | if (--pvc->open_count == 0) { |
| 319 | hdlc_device *hdlc = dev_to_hdlc(pvc->master); | 378 | hdlc_device *hdlc = dev_to_hdlc(pvc->frad); |
| 320 | if (hdlc->state.fr.settings.lmi == LMI_NONE) | 379 | if (state(hdlc)->settings.lmi == LMI_NONE) |
| 321 | pvc->state.active = 0; | 380 | pvc->state.active = 0; |
| 322 | 381 | ||
| 323 | if (hdlc->state.fr.settings.dce) { | 382 | if (state(hdlc)->settings.dce) { |
| 324 | hdlc->state.fr.dce_changed = 1; | 383 | state(hdlc)->dce_changed = 1; |
| 325 | pvc->state.active = 0; | 384 | pvc->state.active = 0; |
| 326 | } | 385 | } |
| 327 | } | 386 | } |
| @@ -348,7 +407,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 348 | } | 407 | } |
| 349 | 408 | ||
| 350 | info.dlci = pvc->dlci; | 409 | info.dlci = pvc->dlci; |
| 351 | memcpy(info.master, pvc->master->name, IFNAMSIZ); | 410 | memcpy(info.master, pvc->frad->name, IFNAMSIZ); |
| 352 | if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, | 411 | if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, |
| 353 | &info, sizeof(info))) | 412 | &info, sizeof(info))) |
| 354 | return -EFAULT; | 413 | return -EFAULT; |
| @@ -361,7 +420,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 361 | 420 | ||
| 362 | static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) | 421 | static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) |
| 363 | { | 422 | { |
| 364 | return netdev_priv(dev); | 423 | return &dev_to_desc(dev)->stats; |
| 365 | } | 424 | } |
| 366 | 425 | ||
| 367 | 426 | ||
| @@ -393,7 +452,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 393 | stats->tx_packets++; | 452 | stats->tx_packets++; |
| 394 | if (pvc->state.fecn) /* TX Congestion counter */ | 453 | if (pvc->state.fecn) /* TX Congestion counter */ |
| 395 | stats->tx_compressed++; | 454 | stats->tx_compressed++; |
| 396 | skb->dev = pvc->master; | 455 | skb->dev = pvc->frad; |
| 397 | dev_queue_xmit(skb); | 456 | dev_queue_xmit(skb); |
| 398 | return 0; | 457 | return 0; |
| 399 | } | 458 | } |
| @@ -419,7 +478,7 @@ static int pvc_change_mtu(struct net_device *dev, int new_mtu) | |||
| 419 | static inline void fr_log_dlci_active(pvc_device *pvc) | 478 | static inline void fr_log_dlci_active(pvc_device *pvc) |
| 420 | { | 479 | { |
| 421 | printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", | 480 | printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", |
| 422 | pvc->master->name, | 481 | pvc->frad->name, |
| 423 | pvc->dlci, | 482 | pvc->dlci, |
| 424 | pvc->main ? pvc->main->name : "", | 483 | pvc->main ? pvc->main->name : "", |
| 425 | pvc->main && pvc->ether ? " " : "", | 484 | pvc->main && pvc->ether ? " " : "", |
| @@ -438,21 +497,20 @@ static inline u8 fr_lmi_nextseq(u8 x) | |||
| 438 | } | 497 | } |
| 439 | 498 | ||
| 440 | 499 | ||
| 441 | |||
| 442 | static void fr_lmi_send(struct net_device *dev, int fullrep) | 500 | static void fr_lmi_send(struct net_device *dev, int fullrep) |
| 443 | { | 501 | { |
| 444 | hdlc_device *hdlc = dev_to_hdlc(dev); | 502 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 445 | struct sk_buff *skb; | 503 | struct sk_buff *skb; |
| 446 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 504 | pvc_device *pvc = state(hdlc)->first_pvc; |
| 447 | int lmi = hdlc->state.fr.settings.lmi; | 505 | int lmi = state(hdlc)->settings.lmi; |
| 448 | int dce = hdlc->state.fr.settings.dce; | 506 | int dce = state(hdlc)->settings.dce; |
| 449 | int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; | 507 | int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; |
| 450 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3; | 508 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3; |
| 451 | u8 *data; | 509 | u8 *data; |
| 452 | int i = 0; | 510 | int i = 0; |
| 453 | 511 | ||
| 454 | if (dce && fullrep) { | 512 | if (dce && fullrep) { |
| 455 | len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); | 513 | len += state(hdlc)->dce_pvc_count * (2 + stat_len); |
| 456 | if (len > HDLC_MAX_MRU) { | 514 | if (len > HDLC_MAX_MRU) { |
| 457 | printk(KERN_WARNING "%s: Too many PVCs while sending " | 515 | printk(KERN_WARNING "%s: Too many PVCs while sending " |
| 458 | "LMI full report\n", dev->name); | 516 | "LMI full report\n", dev->name); |
| @@ -486,8 +544,9 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
| 486 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; | 544 | data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; |
| 487 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; | 545 | data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; |
| 488 | data[i++] = LMI_INTEG_LEN; | 546 | data[i++] = LMI_INTEG_LEN; |
| 489 | data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); | 547 | data[i++] = state(hdlc)->txseq = |
| 490 | data[i++] = hdlc->state.fr.rxseq; | 548 | fr_lmi_nextseq(state(hdlc)->txseq); |
| 549 | data[i++] = state(hdlc)->rxseq; | ||
| 491 | 550 | ||
| 492 | if (dce && fullrep) { | 551 | if (dce && fullrep) { |
| 493 | while (pvc) { | 552 | while (pvc) { |
| @@ -496,7 +555,7 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
| 496 | data[i++] = stat_len; | 555 | data[i++] = stat_len; |
| 497 | 556 | ||
| 498 | /* LMI start/restart */ | 557 | /* LMI start/restart */ |
| 499 | if (hdlc->state.fr.reliable && !pvc->state.exist) { | 558 | if (state(hdlc)->reliable && !pvc->state.exist) { |
| 500 | pvc->state.exist = pvc->state.new = 1; | 559 | pvc->state.exist = pvc->state.new = 1; |
| 501 | fr_log_dlci_active(pvc); | 560 | fr_log_dlci_active(pvc); |
| 502 | } | 561 | } |
| @@ -541,15 +600,15 @@ static void fr_lmi_send(struct net_device *dev, int fullrep) | |||
| 541 | static void fr_set_link_state(int reliable, struct net_device *dev) | 600 | static void fr_set_link_state(int reliable, struct net_device *dev) |
| 542 | { | 601 | { |
| 543 | hdlc_device *hdlc = dev_to_hdlc(dev); | 602 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 544 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 603 | pvc_device *pvc = state(hdlc)->first_pvc; |
| 545 | 604 | ||
| 546 | hdlc->state.fr.reliable = reliable; | 605 | state(hdlc)->reliable = reliable; |
| 547 | if (reliable) { | 606 | if (reliable) { |
| 548 | netif_dormant_off(dev); | 607 | netif_dormant_off(dev); |
| 549 | hdlc->state.fr.n391cnt = 0; /* Request full status */ | 608 | state(hdlc)->n391cnt = 0; /* Request full status */ |
| 550 | hdlc->state.fr.dce_changed = 1; | 609 | state(hdlc)->dce_changed = 1; |
| 551 | 610 | ||
| 552 | if (hdlc->state.fr.settings.lmi == LMI_NONE) { | 611 | if (state(hdlc)->settings.lmi == LMI_NONE) { |
| 553 | while (pvc) { /* Activate all PVCs */ | 612 | while (pvc) { /* Activate all PVCs */ |
| 554 | pvc_carrier(1, pvc); | 613 | pvc_carrier(1, pvc); |
| 555 | pvc->state.exist = pvc->state.active = 1; | 614 | pvc->state.exist = pvc->state.active = 1; |
| @@ -563,7 +622,7 @@ static void fr_set_link_state(int reliable, struct net_device *dev) | |||
| 563 | pvc_carrier(0, pvc); | 622 | pvc_carrier(0, pvc); |
| 564 | pvc->state.exist = pvc->state.active = 0; | 623 | pvc->state.exist = pvc->state.active = 0; |
| 565 | pvc->state.new = 0; | 624 | pvc->state.new = 0; |
| 566 | if (!hdlc->state.fr.settings.dce) | 625 | if (!state(hdlc)->settings.dce) |
| 567 | pvc->state.bandwidth = 0; | 626 | pvc->state.bandwidth = 0; |
| 568 | pvc = pvc->next; | 627 | pvc = pvc->next; |
| 569 | } | 628 | } |
| @@ -571,7 +630,6 @@ static void fr_set_link_state(int reliable, struct net_device *dev) | |||
| 571 | } | 630 | } |
| 572 | 631 | ||
| 573 | 632 | ||
| 574 | |||
| 575 | static void fr_timer(unsigned long arg) | 633 | static void fr_timer(unsigned long arg) |
| 576 | { | 634 | { |
| 577 | struct net_device *dev = (struct net_device *)arg; | 635 | struct net_device *dev = (struct net_device *)arg; |
| @@ -579,62 +637,61 @@ static void fr_timer(unsigned long arg) | |||
| 579 | int i, cnt = 0, reliable; | 637 | int i, cnt = 0, reliable; |
| 580 | u32 list; | 638 | u32 list; |
| 581 | 639 | ||
| 582 | if (hdlc->state.fr.settings.dce) { | 640 | if (state(hdlc)->settings.dce) { |
| 583 | reliable = hdlc->state.fr.request && | 641 | reliable = state(hdlc)->request && |
| 584 | time_before(jiffies, hdlc->state.fr.last_poll + | 642 | time_before(jiffies, state(hdlc)->last_poll + |
| 585 | hdlc->state.fr.settings.t392 * HZ); | 643 | state(hdlc)->settings.t392 * HZ); |
| 586 | hdlc->state.fr.request = 0; | 644 | state(hdlc)->request = 0; |
| 587 | } else { | 645 | } else { |
| 588 | hdlc->state.fr.last_errors <<= 1; /* Shift the list */ | 646 | state(hdlc)->last_errors <<= 1; /* Shift the list */ |
| 589 | if (hdlc->state.fr.request) { | 647 | if (state(hdlc)->request) { |
| 590 | if (hdlc->state.fr.reliable) | 648 | if (state(hdlc)->reliable) |
| 591 | printk(KERN_INFO "%s: No LMI status reply " | 649 | printk(KERN_INFO "%s: No LMI status reply " |
| 592 | "received\n", dev->name); | 650 | "received\n", dev->name); |
| 593 | hdlc->state.fr.last_errors |= 1; | 651 | state(hdlc)->last_errors |= 1; |
| 594 | } | 652 | } |
| 595 | 653 | ||
| 596 | list = hdlc->state.fr.last_errors; | 654 | list = state(hdlc)->last_errors; |
| 597 | for (i = 0; i < hdlc->state.fr.settings.n393; i++, list >>= 1) | 655 | for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1) |
| 598 | cnt += (list & 1); /* errors count */ | 656 | cnt += (list & 1); /* errors count */ |
| 599 | 657 | ||
| 600 | reliable = (cnt < hdlc->state.fr.settings.n392); | 658 | reliable = (cnt < state(hdlc)->settings.n392); |
| 601 | } | 659 | } |
| 602 | 660 | ||
| 603 | if (hdlc->state.fr.reliable != reliable) { | 661 | if (state(hdlc)->reliable != reliable) { |
| 604 | printk(KERN_INFO "%s: Link %sreliable\n", dev->name, | 662 | printk(KERN_INFO "%s: Link %sreliable\n", dev->name, |
| 605 | reliable ? "" : "un"); | 663 | reliable ? "" : "un"); |
| 606 | fr_set_link_state(reliable, dev); | 664 | fr_set_link_state(reliable, dev); |
| 607 | } | 665 | } |
| 608 | 666 | ||
| 609 | if (hdlc->state.fr.settings.dce) | 667 | if (state(hdlc)->settings.dce) |
| 610 | hdlc->state.fr.timer.expires = jiffies + | 668 | state(hdlc)->timer.expires = jiffies + |
| 611 | hdlc->state.fr.settings.t392 * HZ; | 669 | state(hdlc)->settings.t392 * HZ; |
| 612 | else { | 670 | else { |
| 613 | if (hdlc->state.fr.n391cnt) | 671 | if (state(hdlc)->n391cnt) |
| 614 | hdlc->state.fr.n391cnt--; | 672 | state(hdlc)->n391cnt--; |
| 615 | 673 | ||
| 616 | fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); | 674 | fr_lmi_send(dev, state(hdlc)->n391cnt == 0); |
| 617 | 675 | ||
| 618 | hdlc->state.fr.last_poll = jiffies; | 676 | state(hdlc)->last_poll = jiffies; |
| 619 | hdlc->state.fr.request = 1; | 677 | state(hdlc)->request = 1; |
| 620 | hdlc->state.fr.timer.expires = jiffies + | 678 | state(hdlc)->timer.expires = jiffies + |
| 621 | hdlc->state.fr.settings.t391 * HZ; | 679 | state(hdlc)->settings.t391 * HZ; |
| 622 | } | 680 | } |
| 623 | 681 | ||
| 624 | hdlc->state.fr.timer.function = fr_timer; | 682 | state(hdlc)->timer.function = fr_timer; |
| 625 | hdlc->state.fr.timer.data = arg; | 683 | state(hdlc)->timer.data = arg; |
| 626 | add_timer(&hdlc->state.fr.timer); | 684 | add_timer(&state(hdlc)->timer); |
| 627 | } | 685 | } |
| 628 | 686 | ||
| 629 | 687 | ||
| 630 | |||
| 631 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | 688 | static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) |
| 632 | { | 689 | { |
| 633 | hdlc_device *hdlc = dev_to_hdlc(dev); | 690 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 634 | pvc_device *pvc; | 691 | pvc_device *pvc; |
| 635 | u8 rxseq, txseq; | 692 | u8 rxseq, txseq; |
| 636 | int lmi = hdlc->state.fr.settings.lmi; | 693 | int lmi = state(hdlc)->settings.lmi; |
| 637 | int dce = hdlc->state.fr.settings.dce; | 694 | int dce = state(hdlc)->settings.dce; |
| 638 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; | 695 | int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; |
| 639 | 696 | ||
| 640 | if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : | 697 | if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : |
| @@ -645,8 +702,8 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
| 645 | 702 | ||
| 646 | if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : | 703 | if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : |
| 647 | NLPID_CCITT_ANSI_LMI)) { | 704 | NLPID_CCITT_ANSI_LMI)) { |
| 648 | printk(KERN_INFO "%s: Received non-LMI frame with LMI" | 705 | printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n", |
| 649 | " DLCI\n", dev->name); | 706 | dev->name); |
| 650 | return 1; | 707 | return 1; |
| 651 | } | 708 | } |
| 652 | 709 | ||
| @@ -706,53 +763,53 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
| 706 | } | 763 | } |
| 707 | i++; | 764 | i++; |
| 708 | 765 | ||
| 709 | hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ | 766 | state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */ |
| 710 | rxseq = skb->data[i++]; /* Should confirm our sequence */ | 767 | rxseq = skb->data[i++]; /* Should confirm our sequence */ |
| 711 | 768 | ||
| 712 | txseq = hdlc->state.fr.txseq; | 769 | txseq = state(hdlc)->txseq; |
| 713 | 770 | ||
| 714 | if (dce) | 771 | if (dce) |
| 715 | hdlc->state.fr.last_poll = jiffies; | 772 | state(hdlc)->last_poll = jiffies; |
| 716 | 773 | ||
| 717 | error = 0; | 774 | error = 0; |
| 718 | if (!hdlc->state.fr.reliable) | 775 | if (!state(hdlc)->reliable) |
| 719 | error = 1; | 776 | error = 1; |
| 720 | 777 | ||
| 721 | if (rxseq == 0 || rxseq != txseq) { | 778 | if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */ |
| 722 | hdlc->state.fr.n391cnt = 0; /* Ask for full report next time */ | 779 | state(hdlc)->n391cnt = 0; |
| 723 | error = 1; | 780 | error = 1; |
| 724 | } | 781 | } |
| 725 | 782 | ||
| 726 | if (dce) { | 783 | if (dce) { |
| 727 | if (hdlc->state.fr.fullrep_sent && !error) { | 784 | if (state(hdlc)->fullrep_sent && !error) { |
| 728 | /* Stop sending full report - the last one has been confirmed by DTE */ | 785 | /* Stop sending full report - the last one has been confirmed by DTE */ |
| 729 | hdlc->state.fr.fullrep_sent = 0; | 786 | state(hdlc)->fullrep_sent = 0; |
| 730 | pvc = hdlc->state.fr.first_pvc; | 787 | pvc = state(hdlc)->first_pvc; |
| 731 | while (pvc) { | 788 | while (pvc) { |
| 732 | if (pvc->state.new) { | 789 | if (pvc->state.new) { |
| 733 | pvc->state.new = 0; | 790 | pvc->state.new = 0; |
| 734 | 791 | ||
| 735 | /* Tell DTE that new PVC is now active */ | 792 | /* Tell DTE that new PVC is now active */ |
| 736 | hdlc->state.fr.dce_changed = 1; | 793 | state(hdlc)->dce_changed = 1; |
| 737 | } | 794 | } |
| 738 | pvc = pvc->next; | 795 | pvc = pvc->next; |
| 739 | } | 796 | } |
| 740 | } | 797 | } |
| 741 | 798 | ||
| 742 | if (hdlc->state.fr.dce_changed) { | 799 | if (state(hdlc)->dce_changed) { |
| 743 | reptype = LMI_FULLREP; | 800 | reptype = LMI_FULLREP; |
| 744 | hdlc->state.fr.fullrep_sent = 1; | 801 | state(hdlc)->fullrep_sent = 1; |
| 745 | hdlc->state.fr.dce_changed = 0; | 802 | state(hdlc)->dce_changed = 0; |
| 746 | } | 803 | } |
| 747 | 804 | ||
| 748 | hdlc->state.fr.request = 1; /* got request */ | 805 | state(hdlc)->request = 1; /* got request */ |
| 749 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); | 806 | fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); |
| 750 | return 0; | 807 | return 0; |
| 751 | } | 808 | } |
| 752 | 809 | ||
| 753 | /* DTE */ | 810 | /* DTE */ |
| 754 | 811 | ||
| 755 | hdlc->state.fr.request = 0; /* got response, no request pending */ | 812 | state(hdlc)->request = 0; /* got response, no request pending */ |
| 756 | 813 | ||
| 757 | if (error) | 814 | if (error) |
| 758 | return 0; | 815 | return 0; |
| @@ -760,7 +817,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
| 760 | if (reptype != LMI_FULLREP) | 817 | if (reptype != LMI_FULLREP) |
| 761 | return 0; | 818 | return 0; |
| 762 | 819 | ||
| 763 | pvc = hdlc->state.fr.first_pvc; | 820 | pvc = state(hdlc)->first_pvc; |
| 764 | 821 | ||
| 765 | while (pvc) { | 822 | while (pvc) { |
| 766 | pvc->state.deleted = 1; | 823 | pvc->state.deleted = 1; |
| @@ -827,7 +884,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
| 827 | i += stat_len; | 884 | i += stat_len; |
| 828 | } | 885 | } |
| 829 | 886 | ||
| 830 | pvc = hdlc->state.fr.first_pvc; | 887 | pvc = state(hdlc)->first_pvc; |
| 831 | 888 | ||
| 832 | while (pvc) { | 889 | while (pvc) { |
| 833 | if (pvc->state.deleted && pvc->state.exist) { | 890 | if (pvc->state.deleted && pvc->state.exist) { |
| @@ -841,17 +898,16 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) | |||
| 841 | } | 898 | } |
| 842 | 899 | ||
| 843 | /* Next full report after N391 polls */ | 900 | /* Next full report after N391 polls */ |
| 844 | hdlc->state.fr.n391cnt = hdlc->state.fr.settings.n391; | 901 | state(hdlc)->n391cnt = state(hdlc)->settings.n391; |
| 845 | 902 | ||
| 846 | return 0; | 903 | return 0; |
| 847 | } | 904 | } |
| 848 | 905 | ||
| 849 | 906 | ||
| 850 | |||
| 851 | static int fr_rx(struct sk_buff *skb) | 907 | static int fr_rx(struct sk_buff *skb) |
| 852 | { | 908 | { |
| 853 | struct net_device *ndev = skb->dev; | 909 | struct net_device *frad = skb->dev; |
| 854 | hdlc_device *hdlc = dev_to_hdlc(ndev); | 910 | hdlc_device *hdlc = dev_to_hdlc(frad); |
| 855 | fr_hdr *fh = (fr_hdr*)skb->data; | 911 | fr_hdr *fh = (fr_hdr*)skb->data; |
| 856 | u8 *data = skb->data; | 912 | u8 *data = skb->data; |
| 857 | u16 dlci; | 913 | u16 dlci; |
| @@ -864,11 +920,11 @@ static int fr_rx(struct sk_buff *skb) | |||
| 864 | dlci = q922_to_dlci(skb->data); | 920 | dlci = q922_to_dlci(skb->data); |
| 865 | 921 | ||
| 866 | if ((dlci == LMI_CCITT_ANSI_DLCI && | 922 | if ((dlci == LMI_CCITT_ANSI_DLCI && |
| 867 | (hdlc->state.fr.settings.lmi == LMI_ANSI || | 923 | (state(hdlc)->settings.lmi == LMI_ANSI || |
| 868 | hdlc->state.fr.settings.lmi == LMI_CCITT)) || | 924 | state(hdlc)->settings.lmi == LMI_CCITT)) || |
| 869 | (dlci == LMI_CISCO_DLCI && | 925 | (dlci == LMI_CISCO_DLCI && |
| 870 | hdlc->state.fr.settings.lmi == LMI_CISCO)) { | 926 | state(hdlc)->settings.lmi == LMI_CISCO)) { |
| 871 | if (fr_lmi_recv(ndev, skb)) | 927 | if (fr_lmi_recv(frad, skb)) |
| 872 | goto rx_error; | 928 | goto rx_error; |
| 873 | dev_kfree_skb_any(skb); | 929 | dev_kfree_skb_any(skb); |
| 874 | return NET_RX_SUCCESS; | 930 | return NET_RX_SUCCESS; |
| @@ -878,7 +934,7 @@ static int fr_rx(struct sk_buff *skb) | |||
| 878 | if (!pvc) { | 934 | if (!pvc) { |
| 879 | #ifdef DEBUG_PKT | 935 | #ifdef DEBUG_PKT |
| 880 | printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", | 936 | printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", |
| 881 | ndev->name, dlci); | 937 | frad->name, dlci); |
| 882 | #endif | 938 | #endif |
| 883 | dev_kfree_skb_any(skb); | 939 | dev_kfree_skb_any(skb); |
| 884 | return NET_RX_DROP; | 940 | return NET_RX_DROP; |
| @@ -886,7 +942,7 @@ static int fr_rx(struct sk_buff *skb) | |||
| 886 | 942 | ||
| 887 | if (pvc->state.fecn != fh->fecn) { | 943 | if (pvc->state.fecn != fh->fecn) { |
| 888 | #ifdef DEBUG_ECN | 944 | #ifdef DEBUG_ECN |
| 889 | printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", ndev->name, | 945 | printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name, |
| 890 | dlci, fh->fecn ? "N" : "FF"); | 946 | dlci, fh->fecn ? "N" : "FF"); |
| 891 | #endif | 947 | #endif |
| 892 | pvc->state.fecn ^= 1; | 948 | pvc->state.fecn ^= 1; |
| @@ -894,7 +950,7 @@ static int fr_rx(struct sk_buff *skb) | |||
| 894 | 950 | ||
| 895 | if (pvc->state.becn != fh->becn) { | 951 | if (pvc->state.becn != fh->becn) { |
| 896 | #ifdef DEBUG_ECN | 952 | #ifdef DEBUG_ECN |
| 897 | printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", ndev->name, | 953 | printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name, |
| 898 | dlci, fh->becn ? "N" : "FF"); | 954 | dlci, fh->becn ? "N" : "FF"); |
| 899 | #endif | 955 | #endif |
| 900 | pvc->state.becn ^= 1; | 956 | pvc->state.becn ^= 1; |
| @@ -902,7 +958,7 @@ static int fr_rx(struct sk_buff *skb) | |||
| 902 | 958 | ||
| 903 | 959 | ||
| 904 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 960 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
| 905 | hdlc->stats.rx_dropped++; | 961 | dev_to_desc(frad)->stats.rx_dropped++; |
| 906 | return NET_RX_DROP; | 962 | return NET_RX_DROP; |
| 907 | } | 963 | } |
| 908 | 964 | ||
| @@ -938,13 +994,13 @@ static int fr_rx(struct sk_buff *skb) | |||
| 938 | 994 | ||
| 939 | default: | 995 | default: |
| 940 | printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " | 996 | printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " |
| 941 | "PID=%x\n", ndev->name, oui, pid); | 997 | "PID=%x\n", frad->name, oui, pid); |
| 942 | dev_kfree_skb_any(skb); | 998 | dev_kfree_skb_any(skb); |
| 943 | return NET_RX_DROP; | 999 | return NET_RX_DROP; |
| 944 | } | 1000 | } |
| 945 | } else { | 1001 | } else { |
| 946 | printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " | 1002 | printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " |
| 947 | "length = %i\n", ndev->name, data[3], skb->len); | 1003 | "length = %i\n", frad->name, data[3], skb->len); |
| 948 | dev_kfree_skb_any(skb); | 1004 | dev_kfree_skb_any(skb); |
| 949 | return NET_RX_DROP; | 1005 | return NET_RX_DROP; |
| 950 | } | 1006 | } |
| @@ -964,7 +1020,7 @@ static int fr_rx(struct sk_buff *skb) | |||
| 964 | } | 1020 | } |
| 965 | 1021 | ||
| 966 | rx_error: | 1022 | rx_error: |
| 967 | hdlc->stats.rx_errors++; /* Mark error */ | 1023 | dev_to_desc(frad)->stats.rx_errors++; /* Mark error */ |
| 968 | dev_kfree_skb_any(skb); | 1024 | dev_kfree_skb_any(skb); |
| 969 | return NET_RX_DROP; | 1025 | return NET_RX_DROP; |
| 970 | } | 1026 | } |
| @@ -977,44 +1033,42 @@ static void fr_start(struct net_device *dev) | |||
| 977 | #ifdef DEBUG_LINK | 1033 | #ifdef DEBUG_LINK |
| 978 | printk(KERN_DEBUG "fr_start\n"); | 1034 | printk(KERN_DEBUG "fr_start\n"); |
| 979 | #endif | 1035 | #endif |
| 980 | if (hdlc->state.fr.settings.lmi != LMI_NONE) { | 1036 | if (state(hdlc)->settings.lmi != LMI_NONE) { |
| 981 | hdlc->state.fr.reliable = 0; | 1037 | state(hdlc)->reliable = 0; |
| 982 | hdlc->state.fr.dce_changed = 1; | 1038 | state(hdlc)->dce_changed = 1; |
| 983 | hdlc->state.fr.request = 0; | 1039 | state(hdlc)->request = 0; |
| 984 | hdlc->state.fr.fullrep_sent = 0; | 1040 | state(hdlc)->fullrep_sent = 0; |
| 985 | hdlc->state.fr.last_errors = 0xFFFFFFFF; | 1041 | state(hdlc)->last_errors = 0xFFFFFFFF; |
| 986 | hdlc->state.fr.n391cnt = 0; | 1042 | state(hdlc)->n391cnt = 0; |
| 987 | hdlc->state.fr.txseq = hdlc->state.fr.rxseq = 0; | 1043 | state(hdlc)->txseq = state(hdlc)->rxseq = 0; |
| 988 | 1044 | ||
| 989 | init_timer(&hdlc->state.fr.timer); | 1045 | init_timer(&state(hdlc)->timer); |
| 990 | /* First poll after 1 s */ | 1046 | /* First poll after 1 s */ |
| 991 | hdlc->state.fr.timer.expires = jiffies + HZ; | 1047 | state(hdlc)->timer.expires = jiffies + HZ; |
| 992 | hdlc->state.fr.timer.function = fr_timer; | 1048 | state(hdlc)->timer.function = fr_timer; |
| 993 | hdlc->state.fr.timer.data = (unsigned long)dev; | 1049 | state(hdlc)->timer.data = (unsigned long)dev; |
| 994 | add_timer(&hdlc->state.fr.timer); | 1050 | add_timer(&state(hdlc)->timer); |
| 995 | } else | 1051 | } else |
| 996 | fr_set_link_state(1, dev); | 1052 | fr_set_link_state(1, dev); |
| 997 | } | 1053 | } |
| 998 | 1054 | ||
| 999 | 1055 | ||
| 1000 | |||
| 1001 | static void fr_stop(struct net_device *dev) | 1056 | static void fr_stop(struct net_device *dev) |
| 1002 | { | 1057 | { |
| 1003 | hdlc_device *hdlc = dev_to_hdlc(dev); | 1058 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 1004 | #ifdef DEBUG_LINK | 1059 | #ifdef DEBUG_LINK |
| 1005 | printk(KERN_DEBUG "fr_stop\n"); | 1060 | printk(KERN_DEBUG "fr_stop\n"); |
| 1006 | #endif | 1061 | #endif |
| 1007 | if (hdlc->state.fr.settings.lmi != LMI_NONE) | 1062 | if (state(hdlc)->settings.lmi != LMI_NONE) |
| 1008 | del_timer_sync(&hdlc->state.fr.timer); | 1063 | del_timer_sync(&state(hdlc)->timer); |
| 1009 | fr_set_link_state(0, dev); | 1064 | fr_set_link_state(0, dev); |
| 1010 | } | 1065 | } |
| 1011 | 1066 | ||
| 1012 | 1067 | ||
| 1013 | |||
| 1014 | static void fr_close(struct net_device *dev) | 1068 | static void fr_close(struct net_device *dev) |
| 1015 | { | 1069 | { |
| 1016 | hdlc_device *hdlc = dev_to_hdlc(dev); | 1070 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 1017 | pvc_device *pvc = hdlc->state.fr.first_pvc; | 1071 | pvc_device *pvc = state(hdlc)->first_pvc; |
| 1018 | 1072 | ||
| 1019 | while (pvc) { /* Shutdown all PVCs for this FRAD */ | 1073 | while (pvc) { /* Shutdown all PVCs for this FRAD */ |
| 1020 | if (pvc->main) | 1074 | if (pvc->main) |
| @@ -1025,7 +1079,8 @@ static void fr_close(struct net_device *dev) | |||
| 1025 | } | 1079 | } |
| 1026 | } | 1080 | } |
| 1027 | 1081 | ||
| 1028 | static void dlci_setup(struct net_device *dev) | 1082 | |
| 1083 | static void pvc_setup(struct net_device *dev) | ||
| 1029 | { | 1084 | { |
| 1030 | dev->type = ARPHRD_DLCI; | 1085 | dev->type = ARPHRD_DLCI; |
| 1031 | dev->flags = IFF_POINTOPOINT; | 1086 | dev->flags = IFF_POINTOPOINT; |
| @@ -1033,9 +1088,9 @@ static void dlci_setup(struct net_device *dev) | |||
| 1033 | dev->addr_len = 2; | 1088 | dev->addr_len = 2; |
| 1034 | } | 1089 | } |
| 1035 | 1090 | ||
| 1036 | static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) | 1091 | static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) |
| 1037 | { | 1092 | { |
| 1038 | hdlc_device *hdlc = dev_to_hdlc(master); | 1093 | hdlc_device *hdlc = dev_to_hdlc(frad); |
| 1039 | pvc_device *pvc = NULL; | 1094 | pvc_device *pvc = NULL; |
| 1040 | struct net_device *dev; | 1095 | struct net_device *dev; |
| 1041 | int result, used; | 1096 | int result, used; |
| @@ -1044,9 +1099,9 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) | |||
| 1044 | if (type == ARPHRD_ETHER) | 1099 | if (type == ARPHRD_ETHER) |
| 1045 | prefix = "pvceth%d"; | 1100 | prefix = "pvceth%d"; |
| 1046 | 1101 | ||
| 1047 | if ((pvc = add_pvc(master, dlci)) == NULL) { | 1102 | if ((pvc = add_pvc(frad, dlci)) == NULL) { |
| 1048 | printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", | 1103 | printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", |
| 1049 | master->name); | 1104 | frad->name); |
| 1050 | return -ENOBUFS; | 1105 | return -ENOBUFS; |
| 1051 | } | 1106 | } |
| 1052 | 1107 | ||
| @@ -1060,11 +1115,11 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) | |||
| 1060 | "pvceth%d", ether_setup); | 1115 | "pvceth%d", ether_setup); |
| 1061 | else | 1116 | else |
| 1062 | dev = alloc_netdev(sizeof(struct net_device_stats), | 1117 | dev = alloc_netdev(sizeof(struct net_device_stats), |
| 1063 | "pvc%d", dlci_setup); | 1118 | "pvc%d", pvc_setup); |
| 1064 | 1119 | ||
| 1065 | if (!dev) { | 1120 | if (!dev) { |
| 1066 | printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", | 1121 | printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", |
| 1067 | master->name); | 1122 | frad->name); |
| 1068 | delete_unused_pvcs(hdlc); | 1123 | delete_unused_pvcs(hdlc); |
| 1069 | return -ENOBUFS; | 1124 | return -ENOBUFS; |
| 1070 | } | 1125 | } |
| @@ -1102,8 +1157,8 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) | |||
| 1102 | dev->destructor = free_netdev; | 1157 | dev->destructor = free_netdev; |
| 1103 | *get_dev_p(pvc, type) = dev; | 1158 | *get_dev_p(pvc, type) = dev; |
| 1104 | if (!used) { | 1159 | if (!used) { |
| 1105 | hdlc->state.fr.dce_changed = 1; | 1160 | state(hdlc)->dce_changed = 1; |
| 1106 | hdlc->state.fr.dce_pvc_count++; | 1161 | state(hdlc)->dce_pvc_count++; |
| 1107 | } | 1162 | } |
| 1108 | return 0; | 1163 | return 0; |
| 1109 | } | 1164 | } |
| @@ -1128,8 +1183,8 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type) | |||
| 1128 | *get_dev_p(pvc, type) = NULL; | 1183 | *get_dev_p(pvc, type) = NULL; |
| 1129 | 1184 | ||
| 1130 | if (!pvc_is_used(pvc)) { | 1185 | if (!pvc_is_used(pvc)) { |
| 1131 | hdlc->state.fr.dce_pvc_count--; | 1186 | state(hdlc)->dce_pvc_count--; |
| 1132 | hdlc->state.fr.dce_changed = 1; | 1187 | state(hdlc)->dce_changed = 1; |
| 1133 | } | 1188 | } |
| 1134 | delete_unused_pvcs(hdlc); | 1189 | delete_unused_pvcs(hdlc); |
| 1135 | return 0; | 1190 | return 0; |
| @@ -1137,14 +1192,13 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type) | |||
| 1137 | 1192 | ||
| 1138 | 1193 | ||
| 1139 | 1194 | ||
| 1140 | static void fr_destroy(hdlc_device *hdlc) | 1195 | static void fr_destroy(struct net_device *frad) |
| 1141 | { | 1196 | { |
| 1142 | pvc_device *pvc; | 1197 | hdlc_device *hdlc = dev_to_hdlc(frad); |
| 1143 | 1198 | pvc_device *pvc = state(hdlc)->first_pvc; | |
| 1144 | pvc = hdlc->state.fr.first_pvc; | 1199 | state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */ |
| 1145 | hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ | 1200 | state(hdlc)->dce_pvc_count = 0; |
| 1146 | hdlc->state.fr.dce_pvc_count = 0; | 1201 | state(hdlc)->dce_changed = 1; |
| 1147 | hdlc->state.fr.dce_changed = 1; | ||
| 1148 | 1202 | ||
| 1149 | while (pvc) { | 1203 | while (pvc) { |
| 1150 | pvc_device *next = pvc->next; | 1204 | pvc_device *next = pvc->next; |
| @@ -1161,8 +1215,17 @@ static void fr_destroy(hdlc_device *hdlc) | |||
| 1161 | } | 1215 | } |
| 1162 | 1216 | ||
| 1163 | 1217 | ||
| 1218 | static struct hdlc_proto proto = { | ||
| 1219 | .close = fr_close, | ||
| 1220 | .start = fr_start, | ||
| 1221 | .stop = fr_stop, | ||
| 1222 | .detach = fr_destroy, | ||
| 1223 | .ioctl = fr_ioctl, | ||
| 1224 | .module = THIS_MODULE, | ||
| 1225 | }; | ||
| 1226 | |||
| 1164 | 1227 | ||
| 1165 | int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | 1228 | static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) |
| 1166 | { | 1229 | { |
| 1167 | fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; | 1230 | fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; |
| 1168 | const size_t size = sizeof(fr_proto); | 1231 | const size_t size = sizeof(fr_proto); |
| @@ -1173,12 +1236,14 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 1173 | 1236 | ||
| 1174 | switch (ifr->ifr_settings.type) { | 1237 | switch (ifr->ifr_settings.type) { |
| 1175 | case IF_GET_PROTO: | 1238 | case IF_GET_PROTO: |
| 1239 | if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ | ||
| 1240 | return -EINVAL; | ||
| 1176 | ifr->ifr_settings.type = IF_PROTO_FR; | 1241 | ifr->ifr_settings.type = IF_PROTO_FR; |
| 1177 | if (ifr->ifr_settings.size < size) { | 1242 | if (ifr->ifr_settings.size < size) { |
| 1178 | ifr->ifr_settings.size = size; /* data size wanted */ | 1243 | ifr->ifr_settings.size = size; /* data size wanted */ |
| 1179 | return -ENOBUFS; | 1244 | return -ENOBUFS; |
| 1180 | } | 1245 | } |
| 1181 | if (copy_to_user(fr_s, &hdlc->state.fr.settings, size)) | 1246 | if (copy_to_user(fr_s, &state(hdlc)->settings, size)) |
| 1182 | return -EFAULT; | 1247 | return -EFAULT; |
| 1183 | return 0; | 1248 | return 0; |
| 1184 | 1249 | ||
| @@ -1213,20 +1278,16 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 1213 | if (result) | 1278 | if (result) |
| 1214 | return result; | 1279 | return result; |
| 1215 | 1280 | ||
| 1216 | if (hdlc->proto.id != IF_PROTO_FR) { | 1281 | if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */ |
| 1217 | hdlc_proto_detach(hdlc); | 1282 | result = attach_hdlc_protocol(dev, &proto, fr_rx, |
| 1218 | hdlc->state.fr.first_pvc = NULL; | 1283 | sizeof(struct frad_state)); |
| 1219 | hdlc->state.fr.dce_pvc_count = 0; | 1284 | if (result) |
| 1285 | return result; | ||
| 1286 | state(hdlc)->first_pvc = NULL; | ||
| 1287 | state(hdlc)->dce_pvc_count = 0; | ||
| 1220 | } | 1288 | } |
| 1221 | memcpy(&hdlc->state.fr.settings, &new_settings, size); | 1289 | memcpy(&state(hdlc)->settings, &new_settings, size); |
| 1222 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 1290 | |
| 1223 | |||
| 1224 | hdlc->proto.close = fr_close; | ||
| 1225 | hdlc->proto.start = fr_start; | ||
| 1226 | hdlc->proto.stop = fr_stop; | ||
| 1227 | hdlc->proto.detach = fr_destroy; | ||
| 1228 | hdlc->proto.netif_rx = fr_rx; | ||
| 1229 | hdlc->proto.id = IF_PROTO_FR; | ||
| 1230 | dev->hard_start_xmit = hdlc->xmit; | 1291 | dev->hard_start_xmit = hdlc->xmit; |
| 1231 | dev->hard_header = NULL; | 1292 | dev->hard_header = NULL; |
| 1232 | dev->type = ARPHRD_FRAD; | 1293 | dev->type = ARPHRD_FRAD; |
| @@ -1238,6 +1299,9 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 1238 | case IF_PROTO_FR_DEL_PVC: | 1299 | case IF_PROTO_FR_DEL_PVC: |
| 1239 | case IF_PROTO_FR_ADD_ETH_PVC: | 1300 | case IF_PROTO_FR_ADD_ETH_PVC: |
| 1240 | case IF_PROTO_FR_DEL_ETH_PVC: | 1301 | case IF_PROTO_FR_DEL_ETH_PVC: |
| 1302 | if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ | ||
| 1303 | return -EINVAL; | ||
| 1304 | |||
| 1241 | if(!capable(CAP_NET_ADMIN)) | 1305 | if(!capable(CAP_NET_ADMIN)) |
| 1242 | return -EPERM; | 1306 | return -EPERM; |
| 1243 | 1307 | ||
| @@ -1263,3 +1327,24 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 1263 | 1327 | ||
| 1264 | return -EINVAL; | 1328 | return -EINVAL; |
| 1265 | } | 1329 | } |
| 1330 | |||
| 1331 | |||
| 1332 | static int __init mod_init(void) | ||
| 1333 | { | ||
| 1334 | register_hdlc_protocol(&proto); | ||
| 1335 | return 0; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | |||
| 1339 | static void __exit mod_exit(void) | ||
| 1340 | { | ||
| 1341 | unregister_hdlc_protocol(&proto); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | |||
| 1345 | module_init(mod_init); | ||
| 1346 | module_exit(mod_exit); | ||
| 1347 | |||
| 1348 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 1349 | MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC"); | ||
| 1350 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index fbaab5bf71eb..e9f717070fde 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * Point-to-point protocol support | 3 | * Point-to-point protocol support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -22,6 +22,21 @@ | |||
| 22 | #include <linux/lapb.h> | 22 | #include <linux/lapb.h> |
| 23 | #include <linux/rtnetlink.h> | 23 | #include <linux/rtnetlink.h> |
| 24 | #include <linux/hdlc.h> | 24 | #include <linux/hdlc.h> |
| 25 | #include <net/syncppp.h> | ||
| 26 | |||
| 27 | struct ppp_state { | ||
| 28 | struct ppp_device pppdev; | ||
| 29 | struct ppp_device *syncppp_ptr; | ||
| 30 | int (*old_change_mtu)(struct net_device *dev, int new_mtu); | ||
| 31 | }; | ||
| 32 | |||
| 33 | static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 34 | |||
| 35 | |||
| 36 | static inline struct ppp_state* state(hdlc_device *hdlc) | ||
| 37 | { | ||
| 38 | return(struct ppp_state *)(hdlc->state); | ||
| 39 | } | ||
| 25 | 40 | ||
| 26 | 41 | ||
| 27 | static int ppp_open(struct net_device *dev) | 42 | static int ppp_open(struct net_device *dev) |
| @@ -30,16 +45,16 @@ static int ppp_open(struct net_device *dev) | |||
| 30 | void *old_ioctl; | 45 | void *old_ioctl; |
| 31 | int result; | 46 | int result; |
| 32 | 47 | ||
| 33 | dev->priv = &hdlc->state.ppp.syncppp_ptr; | 48 | dev->priv = &state(hdlc)->syncppp_ptr; |
| 34 | hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; | 49 | state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; |
| 35 | hdlc->state.ppp.pppdev.dev = dev; | 50 | state(hdlc)->pppdev.dev = dev; |
| 36 | 51 | ||
| 37 | old_ioctl = dev->do_ioctl; | 52 | old_ioctl = dev->do_ioctl; |
| 38 | hdlc->state.ppp.old_change_mtu = dev->change_mtu; | 53 | state(hdlc)->old_change_mtu = dev->change_mtu; |
| 39 | sppp_attach(&hdlc->state.ppp.pppdev); | 54 | sppp_attach(&state(hdlc)->pppdev); |
| 40 | /* sppp_attach nukes them. We don't need syncppp's ioctl */ | 55 | /* sppp_attach nukes them. We don't need syncppp's ioctl */ |
| 41 | dev->do_ioctl = old_ioctl; | 56 | dev->do_ioctl = old_ioctl; |
| 42 | hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; | 57 | state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO; |
| 43 | dev->type = ARPHRD_PPP; | 58 | dev->type = ARPHRD_PPP; |
| 44 | result = sppp_open(dev); | 59 | result = sppp_open(dev); |
| 45 | if (result) { | 60 | if (result) { |
| @@ -59,7 +74,7 @@ static void ppp_close(struct net_device *dev) | |||
| 59 | sppp_close(dev); | 74 | sppp_close(dev); |
| 60 | sppp_detach(dev); | 75 | sppp_detach(dev); |
| 61 | dev->rebuild_header = NULL; | 76 | dev->rebuild_header = NULL; |
| 62 | dev->change_mtu = hdlc->state.ppp.old_change_mtu; | 77 | dev->change_mtu = state(hdlc)->old_change_mtu; |
| 63 | dev->mtu = HDLC_MAX_MTU; | 78 | dev->mtu = HDLC_MAX_MTU; |
| 64 | dev->hard_header_len = 16; | 79 | dev->hard_header_len = 16; |
| 65 | } | 80 | } |
| @@ -73,13 +88,24 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 73 | 88 | ||
| 74 | 89 | ||
| 75 | 90 | ||
| 76 | int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | 91 | static struct hdlc_proto proto = { |
| 92 | .open = ppp_open, | ||
| 93 | .close = ppp_close, | ||
| 94 | .type_trans = ppp_type_trans, | ||
| 95 | .ioctl = ppp_ioctl, | ||
| 96 | .module = THIS_MODULE, | ||
| 97 | }; | ||
| 98 | |||
| 99 | |||
| 100 | static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
| 77 | { | 101 | { |
| 78 | hdlc_device *hdlc = dev_to_hdlc(dev); | 102 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 79 | int result; | 103 | int result; |
| 80 | 104 | ||
| 81 | switch (ifr->ifr_settings.type) { | 105 | switch (ifr->ifr_settings.type) { |
| 82 | case IF_GET_PROTO: | 106 | case IF_GET_PROTO: |
| 107 | if (dev_to_hdlc(dev)->proto != &proto) | ||
| 108 | return -EINVAL; | ||
| 83 | ifr->ifr_settings.type = IF_PROTO_PPP; | 109 | ifr->ifr_settings.type = IF_PROTO_PPP; |
| 84 | return 0; /* return protocol only, no settable parameters */ | 110 | return 0; /* return protocol only, no settable parameters */ |
| 85 | 111 | ||
| @@ -96,13 +122,10 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 96 | if (result) | 122 | if (result) |
| 97 | return result; | 123 | return result; |
| 98 | 124 | ||
| 99 | hdlc_proto_detach(hdlc); | 125 | result = attach_hdlc_protocol(dev, &proto, NULL, |
| 100 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 126 | sizeof(struct ppp_state)); |
| 101 | 127 | if (result) | |
| 102 | hdlc->proto.open = ppp_open; | 128 | return result; |
| 103 | hdlc->proto.close = ppp_close; | ||
| 104 | hdlc->proto.type_trans = ppp_type_trans; | ||
| 105 | hdlc->proto.id = IF_PROTO_PPP; | ||
| 106 | dev->hard_start_xmit = hdlc->xmit; | 129 | dev->hard_start_xmit = hdlc->xmit; |
| 107 | dev->hard_header = NULL; | 130 | dev->hard_header = NULL; |
| 108 | dev->type = ARPHRD_PPP; | 131 | dev->type = ARPHRD_PPP; |
| @@ -113,3 +136,25 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 113 | 136 | ||
| 114 | return -EINVAL; | 137 | return -EINVAL; |
| 115 | } | 138 | } |
| 139 | |||
| 140 | |||
| 141 | static int __init mod_init(void) | ||
| 142 | { | ||
| 143 | register_hdlc_protocol(&proto); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | |||
| 148 | |||
| 149 | static void __exit mod_exit(void) | ||
| 150 | { | ||
| 151 | unregister_hdlc_protocol(&proto); | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | module_init(mod_init); | ||
| 156 | module_exit(mod_exit); | ||
| 157 | |||
| 158 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 159 | MODULE_DESCRIPTION("PPP protocol support for generic HDLC"); | ||
| 160 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c index f15aa6ba77f1..fe3cae5c6b9d 100644 --- a/drivers/net/wan/hdlc_raw.c +++ b/drivers/net/wan/hdlc_raw.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * HDLC support | 3 | * HDLC support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -24,6 +24,8 @@ | |||
| 24 | #include <linux/hdlc.h> | 24 | #include <linux/hdlc.h> |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 28 | |||
| 27 | static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) | 29 | static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) |
| 28 | { | 30 | { |
| 29 | return __constant_htons(ETH_P_IP); | 31 | return __constant_htons(ETH_P_IP); |
| @@ -31,7 +33,14 @@ static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | 35 | ||
| 34 | int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) | 36 | static struct hdlc_proto proto = { |
| 37 | .type_trans = raw_type_trans, | ||
| 38 | .ioctl = raw_ioctl, | ||
| 39 | .module = THIS_MODULE, | ||
| 40 | }; | ||
| 41 | |||
| 42 | |||
| 43 | static int raw_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
| 35 | { | 44 | { |
| 36 | raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; | 45 | raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; |
| 37 | const size_t size = sizeof(raw_hdlc_proto); | 46 | const size_t size = sizeof(raw_hdlc_proto); |
| @@ -41,12 +50,14 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 41 | 50 | ||
| 42 | switch (ifr->ifr_settings.type) { | 51 | switch (ifr->ifr_settings.type) { |
| 43 | case IF_GET_PROTO: | 52 | case IF_GET_PROTO: |
| 53 | if (dev_to_hdlc(dev)->proto != &proto) | ||
| 54 | return -EINVAL; | ||
| 44 | ifr->ifr_settings.type = IF_PROTO_HDLC; | 55 | ifr->ifr_settings.type = IF_PROTO_HDLC; |
| 45 | if (ifr->ifr_settings.size < size) { | 56 | if (ifr->ifr_settings.size < size) { |
| 46 | ifr->ifr_settings.size = size; /* data size wanted */ | 57 | ifr->ifr_settings.size = size; /* data size wanted */ |
| 47 | return -ENOBUFS; | 58 | return -ENOBUFS; |
| 48 | } | 59 | } |
| 49 | if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) | 60 | if (copy_to_user(raw_s, hdlc->state, size)) |
| 50 | return -EFAULT; | 61 | return -EFAULT; |
| 51 | return 0; | 62 | return 0; |
| 52 | 63 | ||
| @@ -71,12 +82,11 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 71 | if (result) | 82 | if (result) |
| 72 | return result; | 83 | return result; |
| 73 | 84 | ||
| 74 | hdlc_proto_detach(hdlc); | 85 | result = attach_hdlc_protocol(dev, &proto, NULL, |
| 75 | memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); | 86 | sizeof(raw_hdlc_proto)); |
| 76 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 87 | if (result) |
| 77 | 88 | return result; | |
| 78 | hdlc->proto.type_trans = raw_type_trans; | 89 | memcpy(hdlc->state, &new_settings, size); |
| 79 | hdlc->proto.id = IF_PROTO_HDLC; | ||
| 80 | dev->hard_start_xmit = hdlc->xmit; | 90 | dev->hard_start_xmit = hdlc->xmit; |
| 81 | dev->hard_header = NULL; | 91 | dev->hard_header = NULL; |
| 82 | dev->type = ARPHRD_RAWHDLC; | 92 | dev->type = ARPHRD_RAWHDLC; |
| @@ -88,3 +98,25 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 88 | 98 | ||
| 89 | return -EINVAL; | 99 | return -EINVAL; |
| 90 | } | 100 | } |
| 101 | |||
| 102 | |||
| 103 | static int __init mod_init(void) | ||
| 104 | { | ||
| 105 | register_hdlc_protocol(&proto); | ||
| 106 | return 0; | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | |||
| 111 | static void __exit mod_exit(void) | ||
| 112 | { | ||
| 113 | unregister_hdlc_protocol(&proto); | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 117 | module_init(mod_init); | ||
| 118 | module_exit(mod_exit); | ||
| 119 | |||
| 120 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 121 | MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC"); | ||
| 122 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c index d1884987f94e..1a69a9aaa9b9 100644 --- a/drivers/net/wan/hdlc_raw_eth.c +++ b/drivers/net/wan/hdlc_raw_eth.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * HDLC Ethernet emulation support | 3 | * HDLC Ethernet emulation support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 2002-2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
| 26 | #include <linux/hdlc.h> | 26 | #include <linux/hdlc.h> |
| 27 | 27 | ||
| 28 | static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 28 | 29 | ||
| 29 | static int eth_tx(struct sk_buff *skb, struct net_device *dev) | 30 | static int eth_tx(struct sk_buff *skb, struct net_device *dev) |
| 30 | { | 31 | { |
| @@ -44,7 +45,14 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | 47 | ||
| 47 | int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | 48 | static struct hdlc_proto proto = { |
| 49 | .type_trans = eth_type_trans, | ||
| 50 | .ioctl = raw_eth_ioctl, | ||
| 51 | .module = THIS_MODULE, | ||
| 52 | }; | ||
| 53 | |||
| 54 | |||
| 55 | static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
| 48 | { | 56 | { |
| 49 | raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; | 57 | raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; |
| 50 | const size_t size = sizeof(raw_hdlc_proto); | 58 | const size_t size = sizeof(raw_hdlc_proto); |
| @@ -56,12 +64,14 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 56 | 64 | ||
| 57 | switch (ifr->ifr_settings.type) { | 65 | switch (ifr->ifr_settings.type) { |
| 58 | case IF_GET_PROTO: | 66 | case IF_GET_PROTO: |
| 67 | if (dev_to_hdlc(dev)->proto != &proto) | ||
| 68 | return -EINVAL; | ||
| 59 | ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; | 69 | ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; |
| 60 | if (ifr->ifr_settings.size < size) { | 70 | if (ifr->ifr_settings.size < size) { |
| 61 | ifr->ifr_settings.size = size; /* data size wanted */ | 71 | ifr->ifr_settings.size = size; /* data size wanted */ |
| 62 | return -ENOBUFS; | 72 | return -ENOBUFS; |
| 63 | } | 73 | } |
| 64 | if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) | 74 | if (copy_to_user(raw_s, hdlc->state, size)) |
| 65 | return -EFAULT; | 75 | return -EFAULT; |
| 66 | return 0; | 76 | return 0; |
| 67 | 77 | ||
| @@ -86,12 +96,11 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 86 | if (result) | 96 | if (result) |
| 87 | return result; | 97 | return result; |
| 88 | 98 | ||
| 89 | hdlc_proto_detach(hdlc); | 99 | result = attach_hdlc_protocol(dev, &proto, NULL, |
| 90 | memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); | 100 | sizeof(raw_hdlc_proto)); |
| 91 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 101 | if (result) |
| 92 | 102 | return result; | |
| 93 | hdlc->proto.type_trans = eth_type_trans; | 103 | memcpy(hdlc->state, &new_settings, size); |
| 94 | hdlc->proto.id = IF_PROTO_HDLC_ETH; | ||
| 95 | dev->hard_start_xmit = eth_tx; | 104 | dev->hard_start_xmit = eth_tx; |
| 96 | old_ch_mtu = dev->change_mtu; | 105 | old_ch_mtu = dev->change_mtu; |
| 97 | old_qlen = dev->tx_queue_len; | 106 | old_qlen = dev->tx_queue_len; |
| @@ -106,3 +115,25 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 106 | 115 | ||
| 107 | return -EINVAL; | 116 | return -EINVAL; |
| 108 | } | 117 | } |
| 118 | |||
| 119 | |||
| 120 | static int __init mod_init(void) | ||
| 121 | { | ||
| 122 | register_hdlc_protocol(&proto); | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 127 | |||
| 128 | static void __exit mod_exit(void) | ||
| 129 | { | ||
| 130 | unregister_hdlc_protocol(&proto); | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | module_init(mod_init); | ||
| 135 | module_exit(mod_exit); | ||
| 136 | |||
| 137 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 138 | MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC"); | ||
| 139 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index a867fb411f89..e4bb9f8ad433 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
| 3 | * X.25 support | 3 | * X.25 support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 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 | 8 | * under the terms of version 2 of the GNU General Public License |
| @@ -25,6 +25,8 @@ | |||
| 25 | 25 | ||
| 26 | #include <net/x25device.h> | 26 | #include <net/x25device.h> |
| 27 | 27 | ||
| 28 | static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
| 29 | |||
| 28 | /* These functions are callbacks called by LAPB layer */ | 30 | /* These functions are callbacks called by LAPB layer */ |
| 29 | 31 | ||
| 30 | static void x25_connect_disconnect(struct net_device *dev, int reason, int code) | 32 | static void x25_connect_disconnect(struct net_device *dev, int reason, int code) |
| @@ -162,30 +164,39 @@ static void x25_close(struct net_device *dev) | |||
| 162 | 164 | ||
| 163 | static int x25_rx(struct sk_buff *skb) | 165 | static int x25_rx(struct sk_buff *skb) |
| 164 | { | 166 | { |
| 165 | hdlc_device *hdlc = dev_to_hdlc(skb->dev); | 167 | struct hdlc_device_desc *desc = dev_to_desc(skb->dev); |
| 166 | 168 | ||
| 167 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 169 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { |
| 168 | hdlc->stats.rx_dropped++; | 170 | desc->stats.rx_dropped++; |
| 169 | return NET_RX_DROP; | 171 | return NET_RX_DROP; |
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | if (lapb_data_received(skb->dev, skb) == LAPB_OK) | 174 | if (lapb_data_received(skb->dev, skb) == LAPB_OK) |
| 173 | return NET_RX_SUCCESS; | 175 | return NET_RX_SUCCESS; |
| 174 | 176 | ||
| 175 | hdlc->stats.rx_errors++; | 177 | desc->stats.rx_errors++; |
| 176 | dev_kfree_skb_any(skb); | 178 | dev_kfree_skb_any(skb); |
| 177 | return NET_RX_DROP; | 179 | return NET_RX_DROP; |
| 178 | } | 180 | } |
| 179 | 181 | ||
| 180 | 182 | ||
| 183 | static struct hdlc_proto proto = { | ||
| 184 | .open = x25_open, | ||
| 185 | .close = x25_close, | ||
| 186 | .ioctl = x25_ioctl, | ||
| 187 | .module = THIS_MODULE, | ||
| 188 | }; | ||
| 189 | |||
| 181 | 190 | ||
| 182 | int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) | 191 | static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) |
| 183 | { | 192 | { |
| 184 | hdlc_device *hdlc = dev_to_hdlc(dev); | 193 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 185 | int result; | 194 | int result; |
| 186 | 195 | ||
| 187 | switch (ifr->ifr_settings.type) { | 196 | switch (ifr->ifr_settings.type) { |
| 188 | case IF_GET_PROTO: | 197 | case IF_GET_PROTO: |
| 198 | if (dev_to_hdlc(dev)->proto != &proto) | ||
| 199 | return -EINVAL; | ||
| 189 | ifr->ifr_settings.type = IF_PROTO_X25; | 200 | ifr->ifr_settings.type = IF_PROTO_X25; |
| 190 | return 0; /* return protocol only, no settable parameters */ | 201 | return 0; /* return protocol only, no settable parameters */ |
| 191 | 202 | ||
| @@ -200,14 +211,9 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 200 | if (result) | 211 | if (result) |
| 201 | return result; | 212 | return result; |
| 202 | 213 | ||
| 203 | hdlc_proto_detach(hdlc); | 214 | if ((result = attach_hdlc_protocol(dev, &proto, |
| 204 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 215 | x25_rx, 0)) != 0) |
| 205 | 216 | return result; | |
| 206 | hdlc->proto.open = x25_open; | ||
| 207 | hdlc->proto.close = x25_close; | ||
| 208 | hdlc->proto.netif_rx = x25_rx; | ||
| 209 | hdlc->proto.type_trans = NULL; | ||
| 210 | hdlc->proto.id = IF_PROTO_X25; | ||
| 211 | dev->hard_start_xmit = x25_xmit; | 217 | dev->hard_start_xmit = x25_xmit; |
| 212 | dev->hard_header = NULL; | 218 | dev->hard_header = NULL; |
| 213 | dev->type = ARPHRD_X25; | 219 | dev->type = ARPHRD_X25; |
| @@ -218,3 +224,25 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
| 218 | 224 | ||
| 219 | return -EINVAL; | 225 | return -EINVAL; |
| 220 | } | 226 | } |
| 227 | |||
| 228 | |||
| 229 | static int __init mod_init(void) | ||
| 230 | { | ||
| 231 | register_hdlc_protocol(&proto); | ||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | static void __exit mod_exit(void) | ||
| 238 | { | ||
| 239 | unregister_hdlc_protocol(&proto); | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | module_init(mod_init); | ||
| 244 | module_exit(mod_exit); | ||
| 245 | |||
| 246 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
| 247 | MODULE_DESCRIPTION("X.25 protocol support for generic HDLC"); | ||
| 248 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h index 2024b26b99e6..63e9fcf31fb8 100644 --- a/drivers/net/wan/pc300.h +++ b/drivers/net/wan/pc300.h | |||
| @@ -100,6 +100,7 @@ | |||
| 100 | #define _PC300_H | 100 | #define _PC300_H |
| 101 | 101 | ||
| 102 | #include <linux/hdlc.h> | 102 | #include <linux/hdlc.h> |
| 103 | #include <net/syncppp.h> | ||
| 103 | #include "hd64572.h" | 104 | #include "hd64572.h" |
| 104 | #include "pc300-falc-lh.h" | 105 | #include "pc300-falc-lh.h" |
| 105 | 106 | ||
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 56e69403d178..8d9b959bf15b 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
| @@ -2016,7 +2016,6 @@ static void sca_intr(pc300_t * card) | |||
| 2016 | pc300ch_t *chan = &card->chan[ch]; | 2016 | pc300ch_t *chan = &card->chan[ch]; |
| 2017 | pc300dev_t *d = &chan->d; | 2017 | pc300dev_t *d = &chan->d; |
| 2018 | struct net_device *dev = d->dev; | 2018 | struct net_device *dev = d->dev; |
| 2019 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 2020 | 2019 | ||
| 2021 | spin_lock(&card->card_lock); | 2020 | spin_lock(&card->card_lock); |
| 2022 | 2021 | ||
| @@ -2049,8 +2048,8 @@ static void sca_intr(pc300_t * card) | |||
| 2049 | } | 2048 | } |
| 2050 | cpc_net_rx(dev); | 2049 | cpc_net_rx(dev); |
| 2051 | /* Discard invalid frames */ | 2050 | /* Discard invalid frames */ |
| 2052 | hdlc->stats.rx_errors++; | 2051 | hdlc_stats(dev)->rx_errors++; |
| 2053 | hdlc->stats.rx_over_errors++; | 2052 | hdlc_stats(dev)->rx_over_errors++; |
| 2054 | chan->rx_first_bd = 0; | 2053 | chan->rx_first_bd = 0; |
| 2055 | chan->rx_last_bd = N_DMA_RX_BUF - 1; | 2054 | chan->rx_last_bd = N_DMA_RX_BUF - 1; |
| 2056 | rx_dma_start(card, ch); | 2055 | rx_dma_start(card, ch); |
| @@ -2116,8 +2115,8 @@ static void sca_intr(pc300_t * card) | |||
| 2116 | card->hw.cpld_reg2) & | 2115 | card->hw.cpld_reg2) & |
| 2117 | ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); | 2116 | ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); |
| 2118 | } | 2117 | } |
| 2119 | hdlc->stats.tx_errors++; | 2118 | hdlc_stats(dev)->tx_errors++; |
| 2120 | hdlc->stats.tx_fifo_errors++; | 2119 | hdlc_stats(dev)->tx_fifo_errors++; |
| 2121 | sca_tx_intr(d); | 2120 | sca_tx_intr(d); |
| 2122 | } | 2121 | } |
| 2123 | } | 2122 | } |
| @@ -2534,7 +2533,6 @@ static int cpc_change_mtu(struct net_device *dev, int new_mtu) | |||
| 2534 | 2533 | ||
| 2535 | static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 2534 | static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 2536 | { | 2535 | { |
| 2537 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 2538 | pc300dev_t *d = (pc300dev_t *) dev->priv; | 2536 | pc300dev_t *d = (pc300dev_t *) dev->priv; |
| 2539 | pc300ch_t *chan = (pc300ch_t *) d->chan; | 2537 | pc300ch_t *chan = (pc300ch_t *) d->chan; |
| 2540 | pc300_t *card = (pc300_t *) chan->card; | 2538 | pc300_t *card = (pc300_t *) chan->card; |
| @@ -2552,10 +2550,10 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 2552 | case SIOCGPC300CONF: | 2550 | case SIOCGPC300CONF: |
| 2553 | #ifdef CONFIG_PC300_MLPPP | 2551 | #ifdef CONFIG_PC300_MLPPP |
| 2554 | if (conf->proto != PC300_PROTO_MLPPP) { | 2552 | if (conf->proto != PC300_PROTO_MLPPP) { |
| 2555 | conf->proto = hdlc->proto.id; | 2553 | conf->proto = /* FIXME hdlc->proto.id */ 0; |
| 2556 | } | 2554 | } |
| 2557 | #else | 2555 | #else |
| 2558 | conf->proto = hdlc->proto.id; | 2556 | conf->proto = /* FIXME hdlc->proto.id */ 0; |
| 2559 | #endif | 2557 | #endif |
| 2560 | memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); | 2558 | memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); |
| 2561 | memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); | 2559 | memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); |
| @@ -2588,12 +2586,12 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 2588 | } | 2586 | } |
| 2589 | } else { | 2587 | } else { |
| 2590 | memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); | 2588 | memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); |
| 2591 | hdlc->proto.id = conf->proto; | 2589 | /* FIXME hdlc->proto.id = conf->proto; */ |
| 2592 | } | 2590 | } |
| 2593 | } | 2591 | } |
| 2594 | #else | 2592 | #else |
| 2595 | memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); | 2593 | memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); |
| 2596 | hdlc->proto.id = conf->proto; | 2594 | /* FIXME hdlc->proto.id = conf->proto; */ |
| 2597 | #endif | 2595 | #endif |
| 2598 | return 0; | 2596 | return 0; |
| 2599 | case SIOCGPC300STATUS: | 2597 | case SIOCGPC300STATUS: |
| @@ -2606,7 +2604,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 2606 | case SIOCGPC300UTILSTATS: | 2604 | case SIOCGPC300UTILSTATS: |
| 2607 | { | 2605 | { |
| 2608 | if (!arg) { /* clear statistics */ | 2606 | if (!arg) { /* clear statistics */ |
| 2609 | memset(&hdlc->stats, 0, sizeof(struct net_device_stats)); | 2607 | memset(hdlc_stats(dev), 0, sizeof(struct net_device_stats)); |
| 2610 | if (card->hw.type == PC300_TE) { | 2608 | if (card->hw.type == PC300_TE) { |
| 2611 | memset(&chan->falc, 0, sizeof(falc_t)); | 2609 | memset(&chan->falc, 0, sizeof(falc_t)); |
| 2612 | } | 2610 | } |
| @@ -2617,7 +2615,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 2617 | pc300stats.hw_type = card->hw.type; | 2615 | pc300stats.hw_type = card->hw.type; |
| 2618 | pc300stats.line_on = card->chan[ch].d.line_on; | 2616 | pc300stats.line_on = card->chan[ch].d.line_on; |
| 2619 | pc300stats.line_off = card->chan[ch].d.line_off; | 2617 | pc300stats.line_off = card->chan[ch].d.line_off; |
| 2620 | memcpy(&pc300stats.gen_stats, &hdlc->stats, | 2618 | memcpy(&pc300stats.gen_stats, hdlc_stats(dev), |
| 2621 | sizeof(struct net_device_stats)); | 2619 | sizeof(struct net_device_stats)); |
| 2622 | if (card->hw.type == PC300_TE) | 2620 | if (card->hw.type == PC300_TE) |
| 2623 | memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); | 2621 | memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); |
| @@ -3147,7 +3145,6 @@ static void cpc_closech(pc300dev_t * d) | |||
| 3147 | 3145 | ||
| 3148 | int cpc_open(struct net_device *dev) | 3146 | int cpc_open(struct net_device *dev) |
| 3149 | { | 3147 | { |
| 3150 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 3151 | pc300dev_t *d = (pc300dev_t *) dev->priv; | 3148 | pc300dev_t *d = (pc300dev_t *) dev->priv; |
| 3152 | struct ifreq ifr; | 3149 | struct ifreq ifr; |
| 3153 | int result; | 3150 | int result; |
| @@ -3156,12 +3153,14 @@ int cpc_open(struct net_device *dev) | |||
| 3156 | printk("pc300: cpc_open"); | 3153 | printk("pc300: cpc_open"); |
| 3157 | #endif | 3154 | #endif |
| 3158 | 3155 | ||
| 3156 | #ifdef FIXME | ||
| 3159 | if (hdlc->proto.id == IF_PROTO_PPP) { | 3157 | if (hdlc->proto.id == IF_PROTO_PPP) { |
| 3160 | d->if_ptr = &hdlc->state.ppp.pppdev; | 3158 | d->if_ptr = &hdlc->state.ppp.pppdev; |
| 3161 | } | 3159 | } |
| 3160 | #endif | ||
| 3162 | 3161 | ||
| 3163 | result = hdlc_open(dev); | 3162 | result = hdlc_open(dev); |
| 3164 | if (hdlc->proto.id == IF_PROTO_PPP) { | 3163 | if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) { |
| 3165 | dev->priv = d; | 3164 | dev->priv = d; |
| 3166 | } | 3165 | } |
| 3167 | if (result) { | 3166 | if (result) { |
| @@ -3176,7 +3175,6 @@ int cpc_open(struct net_device *dev) | |||
| 3176 | 3175 | ||
| 3177 | static int cpc_close(struct net_device *dev) | 3176 | static int cpc_close(struct net_device *dev) |
| 3178 | { | 3177 | { |
| 3179 | hdlc_device *hdlc = dev_to_hdlc(dev); | ||
| 3180 | pc300dev_t *d = (pc300dev_t *) dev->priv; | 3178 | pc300dev_t *d = (pc300dev_t *) dev->priv; |
| 3181 | pc300ch_t *chan = (pc300ch_t *) d->chan; | 3179 | pc300ch_t *chan = (pc300ch_t *) d->chan; |
| 3182 | pc300_t *card = (pc300_t *) chan->card; | 3180 | pc300_t *card = (pc300_t *) chan->card; |
| @@ -3193,7 +3191,7 @@ static int cpc_close(struct net_device *dev) | |||
| 3193 | CPC_UNLOCK(card, flags); | 3191 | CPC_UNLOCK(card, flags); |
| 3194 | 3192 | ||
| 3195 | hdlc_close(dev); | 3193 | hdlc_close(dev); |
| 3196 | if (hdlc->proto.id == IF_PROTO_PPP) { | 3194 | if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) { |
| 3197 | d->if_ptr = NULL; | 3195 | d->if_ptr = NULL; |
| 3198 | } | 3196 | } |
| 3199 | #ifdef CONFIG_PC300_MLPPP | 3197 | #ifdef CONFIG_PC300_MLPPP |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index bff04cba3fed..ba737c6cebec 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
| @@ -5868,7 +5868,7 @@ static int airo_set_essid(struct net_device *dev, | |||
| 5868 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; | 5868 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; |
| 5869 | 5869 | ||
| 5870 | /* Check the size of the string */ | 5870 | /* Check the size of the string */ |
| 5871 | if(dwrq->length > IW_ESSID_MAX_SIZE+1) { | 5871 | if(dwrq->length > IW_ESSID_MAX_SIZE) { |
| 5872 | return -E2BIG ; | 5872 | return -E2BIG ; |
| 5873 | } | 5873 | } |
| 5874 | /* Check if index is valid */ | 5874 | /* Check if index is valid */ |
| @@ -5880,7 +5880,7 @@ static int airo_set_essid(struct net_device *dev, | |||
| 5880 | memset(SSID_rid.ssids[index].ssid, 0, | 5880 | memset(SSID_rid.ssids[index].ssid, 0, |
| 5881 | sizeof(SSID_rid.ssids[index].ssid)); | 5881 | sizeof(SSID_rid.ssids[index].ssid)); |
| 5882 | memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); | 5882 | memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); |
| 5883 | SSID_rid.ssids[index].len = dwrq->length - 1; | 5883 | SSID_rid.ssids[index].len = dwrq->length; |
| 5884 | } | 5884 | } |
| 5885 | SSID_rid.len = sizeof(SSID_rid); | 5885 | SSID_rid.len = sizeof(SSID_rid); |
| 5886 | /* Write it to the card */ | 5886 | /* Write it to the card */ |
| @@ -5990,7 +5990,7 @@ static int airo_set_nick(struct net_device *dev, | |||
| 5990 | struct airo_info *local = dev->priv; | 5990 | struct airo_info *local = dev->priv; |
| 5991 | 5991 | ||
| 5992 | /* Check the size of the string */ | 5992 | /* Check the size of the string */ |
| 5993 | if(dwrq->length > 16 + 1) { | 5993 | if(dwrq->length > 16) { |
| 5994 | return -E2BIG; | 5994 | return -E2BIG; |
| 5995 | } | 5995 | } |
| 5996 | readConfigRid(local, 1); | 5996 | readConfigRid(local, 1); |
| @@ -6015,7 +6015,7 @@ static int airo_get_nick(struct net_device *dev, | |||
| 6015 | readConfigRid(local, 1); | 6015 | readConfigRid(local, 1); |
| 6016 | strncpy(extra, local->config.nodeName, 16); | 6016 | strncpy(extra, local->config.nodeName, 16); |
| 6017 | extra[16] = '\0'; | 6017 | extra[16] = '\0'; |
| 6018 | dwrq->length = strlen(extra) + 1; | 6018 | dwrq->length = strlen(extra); |
| 6019 | 6019 | ||
| 6020 | return 0; | 6020 | return 0; |
| 6021 | } | 6021 | } |
| @@ -6767,9 +6767,9 @@ static int airo_set_retry(struct net_device *dev, | |||
| 6767 | } | 6767 | } |
| 6768 | readConfigRid(local, 1); | 6768 | readConfigRid(local, 1); |
| 6769 | if(vwrq->flags & IW_RETRY_LIMIT) { | 6769 | if(vwrq->flags & IW_RETRY_LIMIT) { |
| 6770 | if(vwrq->flags & IW_RETRY_MAX) | 6770 | if(vwrq->flags & IW_RETRY_LONG) |
| 6771 | local->config.longRetryLimit = vwrq->value; | 6771 | local->config.longRetryLimit = vwrq->value; |
| 6772 | else if (vwrq->flags & IW_RETRY_MIN) | 6772 | else if (vwrq->flags & IW_RETRY_SHORT) |
| 6773 | local->config.shortRetryLimit = vwrq->value; | 6773 | local->config.shortRetryLimit = vwrq->value; |
| 6774 | else { | 6774 | else { |
| 6775 | /* No modifier : set both */ | 6775 | /* No modifier : set both */ |
| @@ -6805,14 +6805,14 @@ static int airo_get_retry(struct net_device *dev, | |||
| 6805 | if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { | 6805 | if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { |
| 6806 | vwrq->flags = IW_RETRY_LIFETIME; | 6806 | vwrq->flags = IW_RETRY_LIFETIME; |
| 6807 | vwrq->value = (int)local->config.txLifetime * 1024; | 6807 | vwrq->value = (int)local->config.txLifetime * 1024; |
| 6808 | } else if((vwrq->flags & IW_RETRY_MAX)) { | 6808 | } else if((vwrq->flags & IW_RETRY_LONG)) { |
| 6809 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 6809 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 6810 | vwrq->value = (int)local->config.longRetryLimit; | 6810 | vwrq->value = (int)local->config.longRetryLimit; |
| 6811 | } else { | 6811 | } else { |
| 6812 | vwrq->flags = IW_RETRY_LIMIT; | 6812 | vwrq->flags = IW_RETRY_LIMIT; |
| 6813 | vwrq->value = (int)local->config.shortRetryLimit; | 6813 | vwrq->value = (int)local->config.shortRetryLimit; |
| 6814 | if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit) | 6814 | if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit) |
| 6815 | vwrq->flags |= IW_RETRY_MIN; | 6815 | vwrq->flags |= IW_RETRY_SHORT; |
| 6816 | } | 6816 | } |
| 6817 | 6817 | ||
| 6818 | return 0; | 6818 | return 0; |
| @@ -6990,6 +6990,7 @@ static int airo_set_power(struct net_device *dev, | |||
| 6990 | local->config.rmode |= RXMODE_BC_MC_ADDR; | 6990 | local->config.rmode |= RXMODE_BC_MC_ADDR; |
| 6991 | set_bit (FLAG_COMMIT, &local->flags); | 6991 | set_bit (FLAG_COMMIT, &local->flags); |
| 6992 | case IW_POWER_ON: | 6992 | case IW_POWER_ON: |
| 6993 | /* This is broken, fixme ;-) */ | ||
| 6993 | break; | 6994 | break; |
| 6994 | default: | 6995 | default: |
| 6995 | return -EINVAL; | 6996 | return -EINVAL; |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 995c7bea5897..0fc267d626dc 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
| @@ -1656,13 +1656,13 @@ static int atmel_set_essid(struct net_device *dev, | |||
| 1656 | priv->connect_to_any_BSS = 0; | 1656 | priv->connect_to_any_BSS = 0; |
| 1657 | 1657 | ||
| 1658 | /* Check the size of the string */ | 1658 | /* Check the size of the string */ |
| 1659 | if (dwrq->length > MAX_SSID_LENGTH + 1) | 1659 | if (dwrq->length > MAX_SSID_LENGTH) |
| 1660 | return -E2BIG; | 1660 | return -E2BIG; |
| 1661 | if (index != 0) | 1661 | if (index != 0) |
| 1662 | return -EINVAL; | 1662 | return -EINVAL; |
| 1663 | 1663 | ||
| 1664 | memcpy(priv->new_SSID, extra, dwrq->length - 1); | 1664 | memcpy(priv->new_SSID, extra, dwrq->length); |
| 1665 | priv->new_SSID_size = dwrq->length - 1; | 1665 | priv->new_SSID_size = dwrq->length; |
| 1666 | } | 1666 | } |
| 1667 | 1667 | ||
| 1668 | return -EINPROGRESS; | 1668 | return -EINPROGRESS; |
| @@ -2120,9 +2120,9 @@ static int atmel_set_retry(struct net_device *dev, | |||
| 2120 | struct atmel_private *priv = netdev_priv(dev); | 2120 | struct atmel_private *priv = netdev_priv(dev); |
| 2121 | 2121 | ||
| 2122 | if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { | 2122 | if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { |
| 2123 | if (vwrq->flags & IW_RETRY_MAX) | 2123 | if (vwrq->flags & IW_RETRY_LONG) |
| 2124 | priv->long_retry = vwrq->value; | 2124 | priv->long_retry = vwrq->value; |
| 2125 | else if (vwrq->flags & IW_RETRY_MIN) | 2125 | else if (vwrq->flags & IW_RETRY_SHORT) |
| 2126 | priv->short_retry = vwrq->value; | 2126 | priv->short_retry = vwrq->value; |
| 2127 | else { | 2127 | else { |
| 2128 | /* No modifier : set both */ | 2128 | /* No modifier : set both */ |
| @@ -2144,15 +2144,15 @@ static int atmel_get_retry(struct net_device *dev, | |||
| 2144 | 2144 | ||
| 2145 | vwrq->disabled = 0; /* Can't be disabled */ | 2145 | vwrq->disabled = 0; /* Can't be disabled */ |
| 2146 | 2146 | ||
| 2147 | /* Note : by default, display the min retry number */ | 2147 | /* Note : by default, display the short retry number */ |
| 2148 | if (vwrq->flags & IW_RETRY_MAX) { | 2148 | if (vwrq->flags & IW_RETRY_LONG) { |
| 2149 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 2149 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 2150 | vwrq->value = priv->long_retry; | 2150 | vwrq->value = priv->long_retry; |
| 2151 | } else { | 2151 | } else { |
| 2152 | vwrq->flags = IW_RETRY_LIMIT; | 2152 | vwrq->flags = IW_RETRY_LIMIT; |
| 2153 | vwrq->value = priv->short_retry; | 2153 | vwrq->value = priv->short_retry; |
| 2154 | if (priv->long_retry != priv->short_retry) | 2154 | if (priv->long_retry != priv->short_retry) |
| 2155 | vwrq->flags |= IW_RETRY_MIN; | 2155 | vwrq->flags |= IW_RETRY_SHORT; |
| 2156 | } | 2156 | } |
| 2157 | 2157 | ||
| 2158 | return 0; | 2158 | return 0; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 6d4ea36bc564..d6a8bf09878e 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
| @@ -666,7 +666,6 @@ struct bcm43xx_noise_calculation { | |||
| 666 | }; | 666 | }; |
| 667 | 667 | ||
| 668 | struct bcm43xx_stats { | 668 | struct bcm43xx_stats { |
| 669 | u8 link_quality; | ||
| 670 | u8 noise; | 669 | u8 noise; |
| 671 | struct iw_statistics wstats; | 670 | struct iw_statistics wstats; |
| 672 | /* Store the last TX/RX times here for updating the leds. */ | 671 | /* Store the last TX/RX times here for updating the leds. */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index 923275ea0789..b9df06a06ea9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | |||
| @@ -54,7 +54,7 @@ static ssize_t write_file_dummy(struct file *file, const char __user *buf, | |||
| 54 | 54 | ||
| 55 | static int open_file_generic(struct inode *inode, struct file *file) | 55 | static int open_file_generic(struct inode *inode, struct file *file) |
| 56 | { | 56 | { |
| 57 | file->private_data = inode->u.generic_ip; | 57 | file->private_data = inode->i_private; |
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index cb9a3ae8463a..eb65db7393ba 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
| @@ -2405,9 +2405,10 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm) | |||
| 2405 | BCM43xx_UCODE_TIME) & 0x1f); | 2405 | BCM43xx_UCODE_TIME) & 0x1f); |
| 2406 | 2406 | ||
| 2407 | if ( value16 > 0x128 ) { | 2407 | if ( value16 > 0x128 ) { |
| 2408 | dprintk(KERN_ERR PFX | 2408 | printk(KERN_ERR PFX |
| 2409 | "Firmware: no support for microcode rev > 0x128\n"); | 2409 | "Firmware: no support for microcode extracted " |
| 2410 | err = -1; | 2410 | "from version 4.x binary drivers.\n"); |
| 2411 | err = -EOPNOTSUPP; | ||
| 2411 | goto err_release_fw; | 2412 | goto err_release_fw; |
| 2412 | } | 2413 | } |
| 2413 | 2414 | ||
| @@ -3169,8 +3170,7 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
| 3169 | * be preemtible. | 3170 | * be preemtible. |
| 3170 | */ | 3171 | */ |
| 3171 | mutex_lock(&bcm->mutex); | 3172 | mutex_lock(&bcm->mutex); |
| 3172 | netif_stop_queue(bcm->net_dev); | 3173 | netif_tx_disable(bcm->net_dev); |
| 3173 | synchronize_net(); | ||
| 3174 | spin_lock_irqsave(&bcm->irq_lock, flags); | 3174 | spin_lock_irqsave(&bcm->irq_lock, flags); |
| 3175 | bcm43xx_mac_suspend(bcm); | 3175 | bcm43xx_mac_suspend(bcm); |
| 3176 | if (bcm43xx_using_pio(bcm)) | 3176 | if (bcm43xx_using_pio(bcm)) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index eafd0f662686..52ce2a9334fb 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c | |||
| @@ -361,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) | |||
| 361 | if (phy->rev <= 2) | 361 | if (phy->rev <= 2) |
| 362 | for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) | 362 | for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) |
| 363 | bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); | 363 | bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); |
| 364 | else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) | 364 | else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) |
| 365 | for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) | 365 | for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) |
| 366 | bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); | 366 | bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); |
| 367 | else | 367 | else |
| @@ -371,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) | |||
| 371 | if (phy->rev == 2) | 371 | if (phy->rev == 2) |
| 372 | for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) | 372 | for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) |
| 373 | bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); | 373 | bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); |
| 374 | else if ((phy->rev > 2) && (phy->rev <= 7)) | 374 | else if ((phy->rev > 2) && (phy->rev <= 8)) |
| 375 | for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) | 375 | for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) |
| 376 | bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); | 376 | bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); |
| 377 | 377 | ||
| @@ -1197,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) | |||
| 1197 | 1197 | ||
| 1198 | if (phy->rev == 1) | 1198 | if (phy->rev == 1) |
| 1199 | bcm43xx_phy_initb5(bcm); | 1199 | bcm43xx_phy_initb5(bcm); |
| 1200 | else if (phy->rev >= 2 && phy->rev <= 7) | 1200 | else |
| 1201 | bcm43xx_phy_initb6(bcm); | 1201 | bcm43xx_phy_initb6(bcm); |
| 1202 | if (phy->rev >= 2 || phy->connected) | 1202 | if (phy->rev >= 2 || phy->connected) |
| 1203 | bcm43xx_phy_inita(bcm); | 1203 | bcm43xx_phy_inita(bcm); |
| @@ -1241,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) | |||
| 1241 | bcm43xx_phy_lo_g_measure(bcm); | 1241 | bcm43xx_phy_lo_g_measure(bcm); |
| 1242 | } else { | 1242 | } else { |
| 1243 | if (radio->version == 0x2050 && radio->revision == 8) { | 1243 | if (radio->version == 0x2050 && radio->revision == 8) { |
| 1244 | //FIXME | 1244 | bcm43xx_radio_write16(bcm, 0x0052, |
| 1245 | (radio->txctl1 << 4) | radio->txctl2); | ||
| 1245 | } else { | 1246 | } else { |
| 1246 | bcm43xx_radio_write16(bcm, 0x0052, | 1247 | bcm43xx_radio_write16(bcm, 0x0052, |
| 1247 | (bcm43xx_radio_read16(bcm, 0x0052) | 1248 | (bcm43xx_radio_read16(bcm, 0x0052) |
| 1248 | & 0xFFF0) | radio->txctl1); | 1249 | & 0xFFF0) | radio->txctl1); |
| 1249 | } | 1250 | } |
| 1250 | if (phy->rev >= 6) { | 1251 | if (phy->rev >= 6) { |
| 1251 | /* | ||
| 1252 | bcm43xx_phy_write(bcm, 0x0036, | 1252 | bcm43xx_phy_write(bcm, 0x0036, |
| 1253 | (bcm43xx_phy_read(bcm, 0x0036) | 1253 | (bcm43xx_phy_read(bcm, 0x0036) |
| 1254 | & 0xF000) | (FIXME << 12)); | 1254 | & 0xF000) | (radio->txctl2 << 12)); |
| 1255 | */ | ||
| 1256 | } | 1255 | } |
| 1257 | if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) | 1256 | if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) |
| 1258 | bcm43xx_phy_write(bcm, 0x002E, 0x8075); | 1257 | bcm43xx_phy_write(bcm, 0x002E, 0x8075); |
| 1259 | else | 1258 | else |
| 1260 | bcm43xx_phy_write(bcm, 0x003E, 0x807F); | 1259 | bcm43xx_phy_write(bcm, 0x002E, 0x807F); |
| 1261 | if (phy->rev < 2) | 1260 | if (phy->rev < 2) |
| 1262 | bcm43xx_phy_write(bcm, 0x002F, 0x0101); | 1261 | bcm43xx_phy_write(bcm, 0x002F, 0x0101); |
| 1263 | else | 1262 | else |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 888077fc14c4..9b7b15cf6561 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
| @@ -334,7 +334,7 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, | |||
| 334 | size_t len; | 334 | size_t len; |
| 335 | 335 | ||
| 336 | mutex_lock(&bcm->mutex); | 336 | mutex_lock(&bcm->mutex); |
| 337 | len = strlen(bcm->nick) + 1; | 337 | len = strlen(bcm->nick); |
| 338 | memcpy(extra, bcm->nick, len); | 338 | memcpy(extra, bcm->nick, len); |
| 339 | data->data.length = (__u16)len; | 339 | data->data.length = (__u16)len; |
| 340 | data->data.flags = 1; | 340 | data->data.flags = 1; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c index c0efbfe605a5..0159e4e93201 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c | |||
| @@ -496,15 +496,14 @@ int bcm43xx_rx(struct bcm43xx_private *bcm, | |||
| 496 | stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, | 496 | stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, |
| 497 | !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), | 497 | !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), |
| 498 | !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); | 498 | !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); |
| 499 | //TODO stats.noise = | 499 | stats.noise = bcm->stats.noise; |
| 500 | if (is_ofdm) | 500 | if (is_ofdm) |
| 501 | stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); | 501 | stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); |
| 502 | else | 502 | else |
| 503 | stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); | 503 | stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); |
| 504 | stats.received_channel = radio->channel; | 504 | stats.received_channel = radio->channel; |
| 505 | //TODO stats.control = | ||
| 506 | stats.mask = IEEE80211_STATMASK_SIGNAL | | 505 | stats.mask = IEEE80211_STATMASK_SIGNAL | |
| 507 | //TODO IEEE80211_STATMASK_NOISE | | 506 | IEEE80211_STATMASK_NOISE | |
| 508 | IEEE80211_STATMASK_RATE | | 507 | IEEE80211_STATMASK_RATE | |
| 509 | IEEE80211_STATMASK_RSSI; | 508 | IEEE80211_STATMASK_RSSI; |
| 510 | if (phy->type == BCM43xx_PHYTYPE_A) | 509 | if (phy->type == BCM43xx_PHYTYPE_A) |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 7a4978516eac..d061fb3443ff 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
| @@ -1412,9 +1412,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev, | |||
| 1412 | /* what could be done, if firmware would support this.. */ | 1412 | /* what could be done, if firmware would support this.. */ |
| 1413 | 1413 | ||
| 1414 | if (rrq->flags & IW_RETRY_LIMIT) { | 1414 | if (rrq->flags & IW_RETRY_LIMIT) { |
| 1415 | if (rrq->flags & IW_RETRY_MAX) | 1415 | if (rrq->flags & IW_RETRY_LONG) |
| 1416 | HFA384X_RID_LONGRETRYLIMIT = rrq->value; | 1416 | HFA384X_RID_LONGRETRYLIMIT = rrq->value; |
| 1417 | else if (rrq->flags & IW_RETRY_MIN) | 1417 | else if (rrq->flags & IW_RETRY_SHORT) |
| 1418 | HFA384X_RID_SHORTRETRYLIMIT = rrq->value; | 1418 | HFA384X_RID_SHORTRETRYLIMIT = rrq->value; |
| 1419 | else { | 1419 | else { |
| 1420 | HFA384X_RID_LONGRETRYLIMIT = rrq->value; | 1420 | HFA384X_RID_LONGRETRYLIMIT = rrq->value; |
| @@ -1468,14 +1468,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev, | |||
| 1468 | rrq->value = le16_to_cpu(altretry); | 1468 | rrq->value = le16_to_cpu(altretry); |
| 1469 | else | 1469 | else |
| 1470 | rrq->value = local->manual_retry_count; | 1470 | rrq->value = local->manual_retry_count; |
| 1471 | } else if ((rrq->flags & IW_RETRY_MAX)) { | 1471 | } else if ((rrq->flags & IW_RETRY_LONG)) { |
| 1472 | rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 1472 | rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 1473 | rrq->value = longretry; | 1473 | rrq->value = longretry; |
| 1474 | } else { | 1474 | } else { |
| 1475 | rrq->flags = IW_RETRY_LIMIT; | 1475 | rrq->flags = IW_RETRY_LIMIT; |
| 1476 | rrq->value = shortretry; | 1476 | rrq->value = shortretry; |
| 1477 | if (shortretry != longretry) | 1477 | if (shortretry != longretry) |
| 1478 | rrq->flags |= IW_RETRY_MIN; | 1478 | rrq->flags |= IW_RETRY_SHORT; |
| 1479 | } | 1479 | } |
| 1480 | } | 1480 | } |
| 1481 | return 0; | 1481 | return 0; |
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index b4d81a04c895..6c5add701a6f 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c | |||
| @@ -6958,7 +6958,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, | |||
| 6958 | } | 6958 | } |
| 6959 | 6959 | ||
| 6960 | if (wrqu->essid.flags && wrqu->essid.length) { | 6960 | if (wrqu->essid.flags && wrqu->essid.length) { |
| 6961 | length = wrqu->essid.length - 1; | 6961 | length = wrqu->essid.length; |
| 6962 | essid = extra; | 6962 | essid = extra; |
| 6963 | } | 6963 | } |
| 6964 | 6964 | ||
| @@ -7051,7 +7051,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev, | |||
| 7051 | 7051 | ||
| 7052 | struct ipw2100_priv *priv = ieee80211_priv(dev); | 7052 | struct ipw2100_priv *priv = ieee80211_priv(dev); |
| 7053 | 7053 | ||
| 7054 | wrqu->data.length = strlen(priv->nick) + 1; | 7054 | wrqu->data.length = strlen(priv->nick); |
| 7055 | memcpy(extra, priv->nick, wrqu->data.length); | 7055 | memcpy(extra, priv->nick, wrqu->data.length); |
| 7056 | wrqu->data.flags = 1; /* active */ | 7056 | wrqu->data.flags = 1; /* active */ |
| 7057 | 7057 | ||
| @@ -7343,14 +7343,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev, | |||
| 7343 | goto done; | 7343 | goto done; |
| 7344 | } | 7344 | } |
| 7345 | 7345 | ||
| 7346 | if (wrqu->retry.flags & IW_RETRY_MIN) { | 7346 | if (wrqu->retry.flags & IW_RETRY_SHORT) { |
| 7347 | err = ipw2100_set_short_retry(priv, wrqu->retry.value); | 7347 | err = ipw2100_set_short_retry(priv, wrqu->retry.value); |
| 7348 | IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", | 7348 | IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", |
| 7349 | wrqu->retry.value); | 7349 | wrqu->retry.value); |
| 7350 | goto done; | 7350 | goto done; |
| 7351 | } | 7351 | } |
| 7352 | 7352 | ||
| 7353 | if (wrqu->retry.flags & IW_RETRY_MAX) { | 7353 | if (wrqu->retry.flags & IW_RETRY_LONG) { |
| 7354 | err = ipw2100_set_long_retry(priv, wrqu->retry.value); | 7354 | err = ipw2100_set_long_retry(priv, wrqu->retry.value); |
| 7355 | IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", | 7355 | IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", |
| 7356 | wrqu->retry.value); | 7356 | wrqu->retry.value); |
| @@ -7383,14 +7383,14 @@ static int ipw2100_wx_get_retry(struct net_device *dev, | |||
| 7383 | if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) | 7383 | if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) |
| 7384 | return -EINVAL; | 7384 | return -EINVAL; |
| 7385 | 7385 | ||
| 7386 | if (wrqu->retry.flags & IW_RETRY_MAX) { | 7386 | if (wrqu->retry.flags & IW_RETRY_LONG) { |
| 7387 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 7387 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 7388 | wrqu->retry.value = priv->long_retry_limit; | 7388 | wrqu->retry.value = priv->long_retry_limit; |
| 7389 | } else { | 7389 | } else { |
| 7390 | wrqu->retry.flags = | 7390 | wrqu->retry.flags = |
| 7391 | (priv->short_retry_limit != | 7391 | (priv->short_retry_limit != |
| 7392 | priv->long_retry_limit) ? | 7392 | priv->long_retry_limit) ? |
| 7393 | IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT; | 7393 | IW_RETRY_LIMIT | IW_RETRY_SHORT : IW_RETRY_LIMIT; |
| 7394 | 7394 | ||
| 7395 | wrqu->retry.value = priv->short_retry_limit; | 7395 | wrqu->retry.value = priv->short_retry_limit; |
| 7396 | } | 7396 | } |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 7358664e0908..5685d7ba55bb 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
| @@ -8875,8 +8875,6 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
| 8875 | } | 8875 | } |
| 8876 | 8876 | ||
| 8877 | length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); | 8877 | length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); |
| 8878 | if (!extra[length - 1]) | ||
| 8879 | length--; | ||
| 8880 | 8878 | ||
| 8881 | priv->config |= CFG_STATIC_ESSID; | 8879 | priv->config |= CFG_STATIC_ESSID; |
| 8882 | 8880 | ||
| @@ -8953,7 +8951,7 @@ static int ipw_wx_get_nick(struct net_device *dev, | |||
| 8953 | struct ipw_priv *priv = ieee80211_priv(dev); | 8951 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 8954 | IPW_DEBUG_WX("Getting nick\n"); | 8952 | IPW_DEBUG_WX("Getting nick\n"); |
| 8955 | mutex_lock(&priv->mutex); | 8953 | mutex_lock(&priv->mutex); |
| 8956 | wrqu->data.length = strlen(priv->nick) + 1; | 8954 | wrqu->data.length = strlen(priv->nick); |
| 8957 | memcpy(extra, priv->nick, wrqu->data.length); | 8955 | memcpy(extra, priv->nick, wrqu->data.length); |
| 8958 | wrqu->data.flags = 1; /* active */ | 8956 | wrqu->data.flags = 1; /* active */ |
| 8959 | mutex_unlock(&priv->mutex); | 8957 | mutex_unlock(&priv->mutex); |
| @@ -9276,9 +9274,9 @@ static int ipw_wx_set_retry(struct net_device *dev, | |||
| 9276 | return -EINVAL; | 9274 | return -EINVAL; |
| 9277 | 9275 | ||
| 9278 | mutex_lock(&priv->mutex); | 9276 | mutex_lock(&priv->mutex); |
| 9279 | if (wrqu->retry.flags & IW_RETRY_MIN) | 9277 | if (wrqu->retry.flags & IW_RETRY_SHORT) |
| 9280 | priv->short_retry_limit = (u8) wrqu->retry.value; | 9278 | priv->short_retry_limit = (u8) wrqu->retry.value; |
| 9281 | else if (wrqu->retry.flags & IW_RETRY_MAX) | 9279 | else if (wrqu->retry.flags & IW_RETRY_LONG) |
| 9282 | priv->long_retry_limit = (u8) wrqu->retry.value; | 9280 | priv->long_retry_limit = (u8) wrqu->retry.value; |
| 9283 | else { | 9281 | else { |
| 9284 | priv->short_retry_limit = (u8) wrqu->retry.value; | 9282 | priv->short_retry_limit = (u8) wrqu->retry.value; |
| @@ -9307,11 +9305,11 @@ static int ipw_wx_get_retry(struct net_device *dev, | |||
| 9307 | return -EINVAL; | 9305 | return -EINVAL; |
| 9308 | } | 9306 | } |
| 9309 | 9307 | ||
| 9310 | if (wrqu->retry.flags & IW_RETRY_MAX) { | 9308 | if (wrqu->retry.flags & IW_RETRY_LONG) { |
| 9311 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 9309 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 9312 | wrqu->retry.value = priv->long_retry_limit; | 9310 | wrqu->retry.value = priv->long_retry_limit; |
| 9313 | } else if (wrqu->retry.flags & IW_RETRY_MIN) { | 9311 | } else if (wrqu->retry.flags & IW_RETRY_SHORT) { |
| 9314 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; | 9312 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; |
| 9315 | wrqu->retry.value = priv->short_retry_limit; | 9313 | wrqu->retry.value = priv->short_retry_limit; |
| 9316 | } else { | 9314 | } else { |
| 9317 | wrqu->retry.flags = IW_RETRY_LIMIT; | 9315 | wrqu->retry.flags = IW_RETRY_LIMIT; |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 1840b69e3cb5..9e19a963febc 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
| @@ -3037,7 +3037,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev, | |||
| 3037 | } | 3037 | } |
| 3038 | 3038 | ||
| 3039 | erq->flags = 1; | 3039 | erq->flags = 1; |
| 3040 | erq->length = strlen(essidbuf) + 1; | 3040 | erq->length = strlen(essidbuf); |
| 3041 | 3041 | ||
| 3042 | return 0; | 3042 | return 0; |
| 3043 | } | 3043 | } |
| @@ -3078,7 +3078,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev, | |||
| 3078 | memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); | 3078 | memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); |
| 3079 | orinoco_unlock(priv, &flags); | 3079 | orinoco_unlock(priv, &flags); |
| 3080 | 3080 | ||
| 3081 | nrq->length = strlen(nickbuf)+1; | 3081 | nrq->length = strlen(nickbuf); |
| 3082 | 3082 | ||
| 3083 | return 0; | 3083 | return 0; |
| 3084 | } | 3084 | } |
| @@ -3575,14 +3575,14 @@ static int orinoco_ioctl_getretry(struct net_device *dev, | |||
| 3575 | rrq->value = lifetime * 1000; /* ??? */ | 3575 | rrq->value = lifetime * 1000; /* ??? */ |
| 3576 | } else { | 3576 | } else { |
| 3577 | /* By default, display the min number */ | 3577 | /* By default, display the min number */ |
| 3578 | if ((rrq->flags & IW_RETRY_MAX)) { | 3578 | if ((rrq->flags & IW_RETRY_LONG)) { |
| 3579 | rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 3579 | rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 3580 | rrq->value = long_limit; | 3580 | rrq->value = long_limit; |
| 3581 | } else { | 3581 | } else { |
| 3582 | rrq->flags = IW_RETRY_LIMIT; | 3582 | rrq->flags = IW_RETRY_LIMIT; |
| 3583 | rrq->value = short_limit; | 3583 | rrq->value = short_limit; |
| 3584 | if(short_limit != long_limit) | 3584 | if(short_limit != long_limit) |
| 3585 | rrq->flags |= IW_RETRY_MIN; | 3585 | rrq->flags |= IW_RETRY_SHORT; |
| 3586 | } | 3586 | } |
| 3587 | } | 3587 | } |
| 3588 | 3588 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index c09fbf733b3a..286325ca3293 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
| @@ -742,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info, | |||
| 742 | 742 | ||
| 743 | /* Check if we were asked for `any' */ | 743 | /* Check if we were asked for `any' */ |
| 744 | if (dwrq->flags && dwrq->length) { | 744 | if (dwrq->flags && dwrq->length) { |
| 745 | if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1)) | 745 | if (dwrq->length > 32) |
| 746 | return -E2BIG; | 746 | return -E2BIG; |
| 747 | essid.length = dwrq->length - 1; | 747 | essid.length = dwrq->length; |
| 748 | memcpy(essid.octets, extra, dwrq->length); | 748 | memcpy(essid.octets, extra, dwrq->length); |
| 749 | } else | 749 | } else |
| 750 | essid.length = 0; | 750 | essid.length = 0; |
| @@ -814,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info, | |||
| 814 | dwrq->length = 0; | 814 | dwrq->length = 0; |
| 815 | 815 | ||
| 816 | down_read(&priv->mib_sem); | 816 | down_read(&priv->mib_sem); |
| 817 | dwrq->length = strlen(priv->nickname) + 1; | 817 | dwrq->length = strlen(priv->nickname); |
| 818 | memcpy(extra, priv->nickname, dwrq->length); | 818 | memcpy(extra, priv->nickname, dwrq->length); |
| 819 | up_read(&priv->mib_sem); | 819 | up_read(&priv->mib_sem); |
| 820 | 820 | ||
| @@ -992,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info, | |||
| 992 | return -EINVAL; | 992 | return -EINVAL; |
| 993 | 993 | ||
| 994 | if (vwrq->flags & IW_RETRY_LIMIT) { | 994 | if (vwrq->flags & IW_RETRY_LIMIT) { |
| 995 | if (vwrq->flags & IW_RETRY_MIN) | 995 | if (vwrq->flags & IW_RETRY_SHORT) |
| 996 | slimit = vwrq->value; | 996 | slimit = vwrq->value; |
| 997 | else if (vwrq->flags & IW_RETRY_MAX) | 997 | else if (vwrq->flags & IW_RETRY_LONG) |
| 998 | llimit = vwrq->value; | 998 | llimit = vwrq->value; |
| 999 | else { | 999 | else { |
| 1000 | /* we are asked to set both */ | 1000 | /* we are asked to set both */ |
| @@ -1035,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info, | |||
| 1035 | mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); | 1035 | mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); |
| 1036 | vwrq->value = r.u * 1024; | 1036 | vwrq->value = r.u * 1024; |
| 1037 | vwrq->flags = IW_RETRY_LIFETIME; | 1037 | vwrq->flags = IW_RETRY_LIFETIME; |
| 1038 | } else if ((vwrq->flags & IW_RETRY_MAX)) { | 1038 | } else if ((vwrq->flags & IW_RETRY_LONG)) { |
| 1039 | /* we are asked for the long retry limit */ | 1039 | /* we are asked for the long retry limit */ |
| 1040 | rvalue |= | 1040 | rvalue |= |
| 1041 | mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); | 1041 | mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); |
| 1042 | vwrq->value = r.u; | 1042 | vwrq->value = r.u; |
| 1043 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 1043 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 1044 | } else { | 1044 | } else { |
| 1045 | /* default. get the short retry limit */ | 1045 | /* default. get the short retry limit */ |
| 1046 | rvalue |= | 1046 | rvalue |= |
| 1047 | mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); | 1047 | mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); |
| 1048 | vwrq->value = r.u; | 1048 | vwrq->value = r.u; |
| 1049 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN; | 1049 | vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; |
| 1050 | } | 1050 | } |
| 1051 | 1051 | ||
| 1052 | return rvalue; | 1052 | return rvalue; |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 4574290f971f..e82548ea609a 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
| @@ -1173,7 +1173,7 @@ static int ray_set_essid(struct net_device *dev, | |||
| 1173 | return -EOPNOTSUPP; | 1173 | return -EOPNOTSUPP; |
| 1174 | } else { | 1174 | } else { |
| 1175 | /* Check the size of the string */ | 1175 | /* Check the size of the string */ |
| 1176 | if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { | 1176 | if(dwrq->length > IW_ESSID_MAX_SIZE) { |
| 1177 | return -E2BIG; | 1177 | return -E2BIG; |
| 1178 | } | 1178 | } |
| 1179 | 1179 | ||
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index e0d294c12970..e3ae5f60d5be 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
| @@ -1802,15 +1802,15 @@ static int wl3501_get_retry(struct net_device *dev, | |||
| 1802 | &retry, sizeof(retry)); | 1802 | &retry, sizeof(retry)); |
| 1803 | if (rc) | 1803 | if (rc) |
| 1804 | goto out; | 1804 | goto out; |
| 1805 | if (wrqu->retry.flags & IW_RETRY_MAX) { | 1805 | if (wrqu->retry.flags & IW_RETRY_LONG) { |
| 1806 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 1806 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; |
| 1807 | goto set_value; | 1807 | goto set_value; |
| 1808 | } | 1808 | } |
| 1809 | rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT, | 1809 | rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT, |
| 1810 | &retry, sizeof(retry)); | 1810 | &retry, sizeof(retry)); |
| 1811 | if (rc) | 1811 | if (rc) |
| 1812 | goto out; | 1812 | goto out; |
| 1813 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; | 1813 | wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; |
| 1814 | set_value: | 1814 | set_value: |
| 1815 | wrqu->retry.value = retry; | 1815 | wrqu->retry.value = retry; |
| 1816 | wrqu->retry.disabled = 0; | 1816 | wrqu->retry.disabled = 0; |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index c52e9bcf8d02..80af9a9fcbb3 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
| @@ -119,7 +119,7 @@ static void zd1201_usbfree(struct urb *urb, struct pt_regs *regs) | |||
| 119 | switch(urb->status) { | 119 | switch(urb->status) { |
| 120 | case -EILSEQ: | 120 | case -EILSEQ: |
| 121 | case -ENODEV: | 121 | case -ENODEV: |
| 122 | case -ETIMEDOUT: | 122 | case -ETIME: |
| 123 | case -ENOENT: | 123 | case -ENOENT: |
| 124 | case -EPIPE: | 124 | case -EPIPE: |
| 125 | case -EOVERFLOW: | 125 | case -EOVERFLOW: |
| @@ -201,7 +201,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs) | |||
| 201 | switch(urb->status) { | 201 | switch(urb->status) { |
| 202 | case -EILSEQ: | 202 | case -EILSEQ: |
| 203 | case -ENODEV: | 203 | case -ENODEV: |
| 204 | case -ETIMEDOUT: | 204 | case -ETIME: |
| 205 | case -ENOENT: | 205 | case -ENOENT: |
| 206 | case -EPIPE: | 206 | case -EPIPE: |
| 207 | case -EOVERFLOW: | 207 | case -EOVERFLOW: |
| @@ -1218,7 +1218,7 @@ static int zd1201_set_essid(struct net_device *dev, | |||
| 1218 | return -EINVAL; | 1218 | return -EINVAL; |
| 1219 | if (data->length < 1) | 1219 | if (data->length < 1) |
| 1220 | data->length = 1; | 1220 | data->length = 1; |
| 1221 | zd->essidlen = data->length-1; | 1221 | zd->essidlen = data->length; |
| 1222 | memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1); | 1222 | memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1); |
| 1223 | memcpy(zd->essid, essid, data->length); | 1223 | memcpy(zd->essid, essid, data->length); |
| 1224 | return zd1201_join(zd, zd->essid, zd->essidlen); | 1224 | return zd1201_join(zd, zd->essid, zd->essidlen); |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 7c4e32cf0d47..aa661b2b76c7 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
| @@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) | |||
| 249 | { | 249 | { |
| 250 | int r; | 250 | int r; |
| 251 | 251 | ||
| 252 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 253 | mutex_lock(&chip->mutex); | 252 | mutex_lock(&chip->mutex); |
| 254 | r = zd_ioread16_locked(chip, value, addr); | 253 | r = zd_ioread16_locked(chip, value, addr); |
| 255 | mutex_unlock(&chip->mutex); | 254 | mutex_unlock(&chip->mutex); |
| @@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value) | |||
| 260 | { | 259 | { |
| 261 | int r; | 260 | int r; |
| 262 | 261 | ||
| 263 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 264 | mutex_lock(&chip->mutex); | 262 | mutex_lock(&chip->mutex); |
| 265 | r = zd_ioread32_locked(chip, value, addr); | 263 | r = zd_ioread32_locked(chip, value, addr); |
| 266 | mutex_unlock(&chip->mutex); | 264 | mutex_unlock(&chip->mutex); |
| @@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value) | |||
| 271 | { | 269 | { |
| 272 | int r; | 270 | int r; |
| 273 | 271 | ||
| 274 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 275 | mutex_lock(&chip->mutex); | 272 | mutex_lock(&chip->mutex); |
| 276 | r = zd_iowrite16_locked(chip, value, addr); | 273 | r = zd_iowrite16_locked(chip, value, addr); |
| 277 | mutex_unlock(&chip->mutex); | 274 | mutex_unlock(&chip->mutex); |
| @@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value) | |||
| 282 | { | 279 | { |
| 283 | int r; | 280 | int r; |
| 284 | 281 | ||
| 285 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 286 | mutex_lock(&chip->mutex); | 282 | mutex_lock(&chip->mutex); |
| 287 | r = zd_iowrite32_locked(chip, value, addr); | 283 | r = zd_iowrite32_locked(chip, value, addr); |
| 288 | mutex_unlock(&chip->mutex); | 284 | mutex_unlock(&chip->mutex); |
| @@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses, | |||
| 294 | { | 290 | { |
| 295 | int r; | 291 | int r; |
| 296 | 292 | ||
| 297 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 298 | mutex_lock(&chip->mutex); | 293 | mutex_lock(&chip->mutex); |
| 299 | r = zd_ioread32v_locked(chip, values, addresses, count); | 294 | r = zd_ioread32v_locked(chip, values, addresses, count); |
| 300 | mutex_unlock(&chip->mutex); | 295 | mutex_unlock(&chip->mutex); |
| @@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | |||
| 306 | { | 301 | { |
| 307 | int r; | 302 | int r; |
| 308 | 303 | ||
| 309 | ZD_ASSERT(!mutex_is_locked(&chip->mutex)); | ||
| 310 | mutex_lock(&chip->mutex); | 304 | mutex_lock(&chip->mutex); |
| 311 | r = zd_iowrite32a_locked(chip, ioreqs, count); | 305 | r = zd_iowrite32a_locked(chip, ioreqs, count); |
| 312 | mutex_unlock(&chip->mutex); | 306 | mutex_unlock(&chip->mutex); |
| @@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type) | |||
| 331 | chip->patch_cr157 = (value >> 13) & 0x1; | 325 | chip->patch_cr157 = (value >> 13) & 0x1; |
| 332 | chip->patch_6m_band_edge = (value >> 21) & 0x1; | 326 | chip->patch_6m_band_edge = (value >> 21) & 0x1; |
| 333 | chip->new_phy_layout = (value >> 31) & 0x1; | 327 | chip->new_phy_layout = (value >> 31) & 0x1; |
| 328 | chip->link_led = ((value >> 4) & 1) ? LED1 : LED2; | ||
| 329 | chip->supports_tx_led = 1; | ||
| 330 | if (value & (1 << 24)) { /* LED scenario */ | ||
| 331 | if (value & (1 << 29)) | ||
| 332 | chip->supports_tx_led = 0; | ||
| 333 | } | ||
| 334 | 334 | ||
| 335 | dev_dbg_f(zd_chip_dev(chip), | 335 | dev_dbg_f(zd_chip_dev(chip), |
| 336 | "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " | 336 | "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " |
| 337 | "patch 6M %d new PHY %d\n", | 337 | "patch 6M %d new PHY %d link LED%d tx led %d\n", |
| 338 | zd_rf_name(*rf_type), *rf_type, | 338 | zd_rf_name(*rf_type), *rf_type, |
| 339 | chip->pa_type, chip->patch_cck_gain, | 339 | chip->pa_type, chip->patch_cck_gain, |
| 340 | chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout); | 340 | chip->patch_cr157, chip->patch_6m_band_edge, |
| 341 | chip->new_phy_layout, | ||
| 342 | chip->link_led == LED1 ? 1 : 2, | ||
| 343 | chip->supports_tx_led); | ||
| 341 | return 0; | 344 | return 0; |
| 342 | error: | 345 | error: |
| 343 | *rf_type = 0; | 346 | *rf_type = 0; |
| @@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel) | |||
| 1181 | u8 value = chip->pwr_int_values[channel - 1]; | 1184 | u8 value = chip->pwr_int_values[channel - 1]; |
| 1182 | dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", | 1185 | dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", |
| 1183 | channel, value); | 1186 | channel, value); |
| 1184 | return zd_iowrite32_locked(chip, value, CR31); | 1187 | return zd_iowrite16_locked(chip, value, CR31); |
| 1185 | } | 1188 | } |
| 1186 | 1189 | ||
| 1187 | static int update_pwr_cal(struct zd_chip *chip, u8 channel) | 1190 | static int update_pwr_cal(struct zd_chip *chip, u8 channel) |
| @@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel) | |||
| 1189 | u8 value = chip->pwr_cal_values[channel-1]; | 1192 | u8 value = chip->pwr_cal_values[channel-1]; |
| 1190 | dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", | 1193 | dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", |
| 1191 | channel, value); | 1194 | channel, value); |
| 1192 | return zd_iowrite32_locked(chip, value, CR68); | 1195 | return zd_iowrite16_locked(chip, value, CR68); |
| 1193 | } | 1196 | } |
| 1194 | 1197 | ||
| 1195 | static int update_ofdm_cal(struct zd_chip *chip, u8 channel) | 1198 | static int update_ofdm_cal(struct zd_chip *chip, u8 channel) |
| 1196 | { | 1199 | { |
| 1197 | struct zd_ioreq32 ioreqs[3]; | 1200 | struct zd_ioreq16 ioreqs[3]; |
| 1198 | 1201 | ||
| 1199 | ioreqs[0].addr = CR67; | 1202 | ioreqs[0].addr = CR67; |
| 1200 | ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; | 1203 | ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; |
| @@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel) | |||
| 1206 | dev_dbg_f(zd_chip_dev(chip), | 1209 | dev_dbg_f(zd_chip_dev(chip), |
| 1207 | "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", | 1210 | "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", |
| 1208 | channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); | 1211 | channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); |
| 1209 | return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); | 1212 | return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); |
| 1210 | } | 1213 | } |
| 1211 | 1214 | ||
| 1212 | static int update_channel_integration_and_calibration(struct zd_chip *chip, | 1215 | static int update_channel_integration_and_calibration(struct zd_chip *chip, |
| @@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, | |||
| 1218 | if (r) | 1221 | if (r) |
| 1219 | return r; | 1222 | return r; |
| 1220 | if (chip->is_zd1211b) { | 1223 | if (chip->is_zd1211b) { |
| 1221 | static const struct zd_ioreq32 ioreqs[] = { | 1224 | static const struct zd_ioreq16 ioreqs[] = { |
| 1222 | { CR69, 0x28 }, | 1225 | { CR69, 0x28 }, |
| 1223 | {}, | 1226 | {}, |
| 1224 | { CR69, 0x2a }, | 1227 | { CR69, 0x2a }, |
| @@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, | |||
| 1230 | r = update_pwr_cal(chip, channel); | 1233 | r = update_pwr_cal(chip, channel); |
| 1231 | if (r) | 1234 | if (r) |
| 1232 | return r; | 1235 | return r; |
| 1233 | r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); | 1236 | r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); |
| 1234 | if (r) | 1237 | if (r) |
| 1235 | return r; | 1238 | return r; |
| 1236 | } | 1239 | } |
| @@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip) | |||
| 1252 | if (r) | 1255 | if (r) |
| 1253 | return r; | 1256 | return r; |
| 1254 | dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); | 1257 | dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); |
| 1255 | return zd_iowrite32_locked(chip, value & 0xff, CR47); | 1258 | return zd_iowrite16_locked(chip, value & 0xff, CR47); |
| 1256 | } | 1259 | } |
| 1257 | 1260 | ||
| 1258 | int zd_chip_set_channel(struct zd_chip *chip, u8 channel) | 1261 | int zd_chip_set_channel(struct zd_chip *chip, u8 channel) |
| @@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip) | |||
| 1295 | return channel; | 1298 | return channel; |
| 1296 | } | 1299 | } |
| 1297 | 1300 | ||
| 1298 | static u16 led_mask(int led) | 1301 | int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) |
| 1299 | { | 1302 | { |
| 1300 | switch (led) { | 1303 | static const zd_addr_t a[] = { |
| 1301 | case 1: | 1304 | FW_LINK_STATUS, |
| 1302 | return LED1; | 1305 | CR_LED, |
| 1303 | case 2: | 1306 | }; |
| 1304 | return LED2; | ||
| 1305 | default: | ||
| 1306 | return 0; | ||
| 1307 | } | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static int read_led_reg(struct zd_chip *chip, u16 *status) | ||
| 1311 | { | ||
| 1312 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | ||
| 1313 | return zd_ioread16_locked(chip, status, CR_LED); | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | static int write_led_reg(struct zd_chip *chip, u16 status) | ||
| 1317 | { | ||
| 1318 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | ||
| 1319 | return zd_iowrite16_locked(chip, status, CR_LED); | ||
| 1320 | } | ||
| 1321 | 1307 | ||
| 1322 | int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status) | 1308 | int r; |
| 1323 | { | 1309 | u16 v[ARRAY_SIZE(a)]; |
| 1324 | int r, ret; | 1310 | struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = { |
| 1325 | u16 mask = led_mask(led); | 1311 | [0] = { FW_LINK_STATUS }, |
| 1326 | u16 reg; | 1312 | [1] = { CR_LED }, |
| 1313 | }; | ||
| 1314 | u16 other_led; | ||
| 1327 | 1315 | ||
| 1328 | if (!mask) | ||
| 1329 | return -EINVAL; | ||
| 1330 | mutex_lock(&chip->mutex); | 1316 | mutex_lock(&chip->mutex); |
| 1331 | r = read_led_reg(chip, ®); | 1317 | r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a)); |
| 1332 | if (r) | 1318 | if (r) |
| 1333 | return r; | 1319 | goto out; |
| 1320 | |||
| 1321 | other_led = chip->link_led == LED1 ? LED2 : LED1; | ||
| 1322 | |||
| 1334 | switch (status) { | 1323 | switch (status) { |
| 1335 | case LED_STATUS: | ||
| 1336 | return (reg & mask) ? LED_ON : LED_OFF; | ||
| 1337 | case LED_OFF: | 1324 | case LED_OFF: |
| 1338 | reg &= ~mask; | 1325 | ioreqs[0].value = FW_LINK_OFF; |
| 1339 | ret = LED_OFF; | 1326 | ioreqs[1].value = v[1] & ~(LED1|LED2); |
| 1340 | break; | 1327 | break; |
| 1341 | case LED_FLIP: | 1328 | case LED_SCANNING: |
| 1342 | reg ^= mask; | 1329 | ioreqs[0].value = FW_LINK_OFF; |
| 1343 | ret = (reg&mask) ? LED_ON : LED_OFF; | 1330 | ioreqs[1].value = v[1] & ~other_led; |
| 1331 | if (get_seconds() % 3 == 0) { | ||
| 1332 | ioreqs[1].value &= ~chip->link_led; | ||
| 1333 | } else { | ||
| 1334 | ioreqs[1].value |= chip->link_led; | ||
| 1335 | } | ||
| 1344 | break; | 1336 | break; |
| 1345 | case LED_ON: | 1337 | case LED_ASSOCIATED: |
| 1346 | reg |= mask; | 1338 | ioreqs[0].value = FW_LINK_TX; |
| 1347 | ret = LED_ON; | 1339 | ioreqs[1].value = v[1] & ~other_led; |
| 1340 | ioreqs[1].value |= chip->link_led; | ||
| 1348 | break; | 1341 | break; |
| 1349 | default: | 1342 | default: |
| 1350 | return -EINVAL; | 1343 | r = -EINVAL; |
| 1351 | } | ||
| 1352 | r = write_led_reg(chip, reg); | ||
| 1353 | if (r) { | ||
| 1354 | ret = r; | ||
| 1355 | goto out; | 1344 | goto out; |
| 1356 | } | 1345 | } |
| 1357 | out: | ||
| 1358 | mutex_unlock(&chip->mutex); | ||
| 1359 | return r; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | int zd_chip_led_flip(struct zd_chip *chip, int led, | ||
| 1363 | const unsigned int *phases_msecs, unsigned int count) | ||
| 1364 | { | ||
| 1365 | int i, r; | ||
| 1366 | enum led_status status; | ||
| 1367 | 1346 | ||
| 1368 | r = zd_chip_led_status(chip, led, LED_STATUS); | 1347 | if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) { |
| 1369 | if (r) | 1348 | r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); |
| 1370 | return r; | 1349 | if (r) |
| 1371 | status = r; | ||
| 1372 | for (i = 0; i < count; i++) { | ||
| 1373 | r = zd_chip_led_status(chip, led, LED_FLIP); | ||
| 1374 | if (r < 0) | ||
| 1375 | goto out; | 1350 | goto out; |
| 1376 | msleep(phases_msecs[i]); | ||
| 1377 | } | 1351 | } |
| 1378 | 1352 | r = 0; | |
| 1379 | out: | 1353 | out: |
| 1380 | zd_chip_led_status(chip, led, status); | 1354 | mutex_unlock(&chip->mutex); |
| 1381 | return r; | 1355 | return r; |
| 1382 | } | 1356 | } |
| 1383 | 1357 | ||
| @@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip, | |||
| 1679 | 1653 | ||
| 1680 | return 0; | 1654 | return 0; |
| 1681 | } | 1655 | } |
| 1682 | |||
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 4b1250859897..ae59597ce4e1 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
| @@ -428,6 +428,7 @@ | |||
| 428 | /* masks for controlling LEDs */ | 428 | /* masks for controlling LEDs */ |
| 429 | #define LED1 0x0100 | 429 | #define LED1 0x0100 |
| 430 | #define LED2 0x0200 | 430 | #define LED2 0x0200 |
| 431 | #define LED_SW 0x0400 | ||
| 431 | 432 | ||
| 432 | /* Seems to indicate that the configuration is over. | 433 | /* Seems to indicate that the configuration is over. |
| 433 | */ | 434 | */ |
| @@ -629,6 +630,10 @@ | |||
| 629 | #define FW_SOFT_RESET FW_REG(4) | 630 | #define FW_SOFT_RESET FW_REG(4) |
| 630 | #define FW_FLASH_CHK FW_REG(5) | 631 | #define FW_FLASH_CHK FW_REG(5) |
| 631 | 632 | ||
| 633 | #define FW_LINK_OFF 0x0 | ||
| 634 | #define FW_LINK_TX 0x1 | ||
| 635 | /* 0x2 - link led on? */ | ||
| 636 | |||
| 632 | enum { | 637 | enum { |
| 633 | CR_BASE_OFFSET = 0x9000, | 638 | CR_BASE_OFFSET = 0x9000, |
| 634 | FW_START_OFFSET = 0xee00, | 639 | FW_START_OFFSET = 0xee00, |
| @@ -663,8 +668,11 @@ struct zd_chip { | |||
| 663 | u8 pwr_int_values[E2P_CHANNEL_COUNT]; | 668 | u8 pwr_int_values[E2P_CHANNEL_COUNT]; |
| 664 | /* SetPointOFDM in the vendor driver */ | 669 | /* SetPointOFDM in the vendor driver */ |
| 665 | u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; | 670 | u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; |
| 666 | u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, | 671 | u16 link_led; |
| 667 | new_phy_layout:1, is_zd1211b:1; | 672 | unsigned int pa_type:4, |
| 673 | patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, | ||
| 674 | new_phy_layout:1, | ||
| 675 | is_zd1211b:1, supports_tx_led:1; | ||
| 668 | }; | 676 | }; |
| 669 | 677 | ||
| 670 | static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) | 678 | static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) |
| @@ -812,15 +820,12 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip); | |||
| 812 | int zd_chip_unlock_phy_regs(struct zd_chip *chip); | 820 | int zd_chip_unlock_phy_regs(struct zd_chip *chip); |
| 813 | 821 | ||
| 814 | enum led_status { | 822 | enum led_status { |
| 815 | LED_OFF = 0, | 823 | LED_OFF = 0, |
| 816 | LED_ON = 1, | 824 | LED_SCANNING = 1, |
| 817 | LED_FLIP = 2, | 825 | LED_ASSOCIATED = 2, |
| 818 | LED_STATUS = 3, | ||
| 819 | }; | 826 | }; |
| 820 | 827 | ||
| 821 | int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status); | 828 | int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); |
| 822 | int zd_chip_led_flip(struct zd_chip *chip, int led, | ||
| 823 | const unsigned int *phases_msecs, unsigned int count); | ||
| 824 | 829 | ||
| 825 | int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); | 830 | int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); |
| 826 | 831 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 1989f1c05fbe..2d12837052b0 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
| @@ -33,6 +33,10 @@ | |||
| 33 | static void ieee_init(struct ieee80211_device *ieee); | 33 | static void ieee_init(struct ieee80211_device *ieee); |
| 34 | static void softmac_init(struct ieee80211softmac_device *sm); | 34 | static void softmac_init(struct ieee80211softmac_device *sm); |
| 35 | 35 | ||
| 36 | static void housekeeping_init(struct zd_mac *mac); | ||
| 37 | static void housekeeping_enable(struct zd_mac *mac); | ||
| 38 | static void housekeeping_disable(struct zd_mac *mac); | ||
| 39 | |||
| 36 | int zd_mac_init(struct zd_mac *mac, | 40 | int zd_mac_init(struct zd_mac *mac, |
| 37 | struct net_device *netdev, | 41 | struct net_device *netdev, |
| 38 | struct usb_interface *intf) | 42 | struct usb_interface *intf) |
| @@ -46,6 +50,7 @@ int zd_mac_init(struct zd_mac *mac, | |||
| 46 | ieee_init(ieee); | 50 | ieee_init(ieee); |
| 47 | softmac_init(ieee80211_priv(netdev)); | 51 | softmac_init(ieee80211_priv(netdev)); |
| 48 | zd_chip_init(&mac->chip, netdev, intf); | 52 | zd_chip_init(&mac->chip, netdev, intf); |
| 53 | housekeeping_init(mac); | ||
| 49 | return 0; | 54 | return 0; |
| 50 | } | 55 | } |
| 51 | 56 | ||
| @@ -178,6 +183,7 @@ int zd_mac_open(struct net_device *netdev) | |||
| 178 | if (r < 0) | 183 | if (r < 0) |
| 179 | goto disable_rx; | 184 | goto disable_rx; |
| 180 | 185 | ||
| 186 | housekeeping_enable(mac); | ||
| 181 | ieee80211softmac_start(netdev); | 187 | ieee80211softmac_start(netdev); |
| 182 | return 0; | 188 | return 0; |
| 183 | disable_rx: | 189 | disable_rx: |
| @@ -204,6 +210,7 @@ int zd_mac_stop(struct net_device *netdev) | |||
| 204 | */ | 210 | */ |
| 205 | 211 | ||
| 206 | zd_chip_disable_rx(chip); | 212 | zd_chip_disable_rx(chip); |
| 213 | housekeeping_disable(mac); | ||
| 207 | ieee80211softmac_stop(netdev); | 214 | ieee80211softmac_stop(netdev); |
| 208 | 215 | ||
| 209 | zd_chip_disable_hwint(chip); | 216 | zd_chip_disable_hwint(chip); |
| @@ -1080,3 +1087,46 @@ void zd_dump_rx_status(const struct rx_status *status) | |||
| 1080 | } | 1087 | } |
| 1081 | } | 1088 | } |
| 1082 | #endif /* DEBUG */ | 1089 | #endif /* DEBUG */ |
| 1090 | |||
| 1091 | #define LINK_LED_WORK_DELAY HZ | ||
| 1092 | |||
| 1093 | static void link_led_handler(void *p) | ||
| 1094 | { | ||
| 1095 | struct zd_mac *mac = p; | ||
| 1096 | struct zd_chip *chip = &mac->chip; | ||
| 1097 | struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); | ||
| 1098 | int is_associated; | ||
| 1099 | int r; | ||
| 1100 | |||
| 1101 | spin_lock_irq(&mac->lock); | ||
| 1102 | is_associated = sm->associated != 0; | ||
| 1103 | spin_unlock_irq(&mac->lock); | ||
| 1104 | |||
| 1105 | r = zd_chip_control_leds(chip, | ||
| 1106 | is_associated ? LED_ASSOCIATED : LED_SCANNING); | ||
| 1107 | if (r) | ||
| 1108 | dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); | ||
| 1109 | |||
| 1110 | queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, | ||
| 1111 | LINK_LED_WORK_DELAY); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | static void housekeeping_init(struct zd_mac *mac) | ||
| 1115 | { | ||
| 1116 | INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac); | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | static void housekeeping_enable(struct zd_mac *mac) | ||
| 1120 | { | ||
| 1121 | dev_dbg_f(zd_mac_dev(mac), "\n"); | ||
| 1122 | queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, | ||
| 1123 | 0); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | static void housekeeping_disable(struct zd_mac *mac) | ||
| 1127 | { | ||
| 1128 | dev_dbg_f(zd_mac_dev(mac), "\n"); | ||
| 1129 | cancel_rearming_delayed_workqueue(zd_workqueue, | ||
| 1130 | &mac->housekeeping.link_led_work); | ||
| 1131 | zd_chip_control_leds(&mac->chip, LED_OFF); | ||
| 1132 | } | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 29b51fd7d4e5..b8ea3de7924a 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
| @@ -120,6 +120,10 @@ enum mac_flags { | |||
| 120 | MAC_FIXED_CHANNEL = 0x01, | 120 | MAC_FIXED_CHANNEL = 0x01, |
| 121 | }; | 121 | }; |
| 122 | 122 | ||
| 123 | struct housekeeping { | ||
| 124 | struct work_struct link_led_work; | ||
| 125 | }; | ||
| 126 | |||
| 123 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 127 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
| 124 | 128 | ||
| 125 | struct zd_mac { | 129 | struct zd_mac { |
| @@ -128,6 +132,7 @@ struct zd_mac { | |||
| 128 | struct net_device *netdev; | 132 | struct net_device *netdev; |
| 129 | /* Unlocked reading possible */ | 133 | /* Unlocked reading possible */ |
| 130 | struct iw_statistics iw_stats; | 134 | struct iw_statistics iw_stats; |
| 135 | struct housekeeping housekeeping; | ||
| 131 | unsigned int stats_count; | 136 | unsigned int stats_count; |
| 132 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | 137 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; |
| 133 | u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | 138 | u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; |
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c index 440ef24b5fd1..af3a7b36d078 100644 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ b/drivers/net/wireless/zd1211rw/zd_netdev.c | |||
| @@ -82,7 +82,7 @@ static int iw_get_nick(struct net_device *netdev, | |||
| 82 | union iwreq_data *req, char *extra) | 82 | union iwreq_data *req, char *extra) |
| 83 | { | 83 | { |
| 84 | strcpy(extra, "zd1211"); | 84 | strcpy(extra, "zd1211"); |
| 85 | req->data.length = strlen(extra) + 1; | 85 | req->data.length = strlen(extra); |
| 86 | req->data.flags = 1; | 86 | req->data.flags = 1; |
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 31027e52b04b..5c265ad0485a 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
| 25 | #include <linux/skbuff.h> | 25 | #include <linux/skbuff.h> |
| 26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
| 27 | #include <linux/workqueue.h> | ||
| 27 | #include <net/ieee80211.h> | 28 | #include <net/ieee80211.h> |
| 28 | 29 | ||
| 29 | #include "zd_def.h" | 30 | #include "zd_def.h" |
| @@ -1112,12 +1113,20 @@ static struct usb_driver driver = { | |||
| 1112 | .disconnect = disconnect, | 1113 | .disconnect = disconnect, |
| 1113 | }; | 1114 | }; |
| 1114 | 1115 | ||
| 1116 | struct workqueue_struct *zd_workqueue; | ||
| 1117 | |||
| 1115 | static int __init usb_init(void) | 1118 | static int __init usb_init(void) |
| 1116 | { | 1119 | { |
| 1117 | int r; | 1120 | int r; |
| 1118 | 1121 | ||
| 1119 | pr_debug("usb_init()\n"); | 1122 | pr_debug("usb_init()\n"); |
| 1120 | 1123 | ||
| 1124 | zd_workqueue = create_singlethread_workqueue(driver.name); | ||
| 1125 | if (zd_workqueue == NULL) { | ||
| 1126 | printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name); | ||
| 1127 | return -ENOMEM; | ||
| 1128 | } | ||
| 1129 | |||
| 1121 | r = usb_register(&driver); | 1130 | r = usb_register(&driver); |
| 1122 | if (r) { | 1131 | if (r) { |
| 1123 | printk(KERN_ERR "usb_register() failed. Error number %d\n", r); | 1132 | printk(KERN_ERR "usb_register() failed. Error number %d\n", r); |
| @@ -1132,6 +1141,7 @@ static void __exit usb_exit(void) | |||
| 1132 | { | 1141 | { |
| 1133 | pr_debug("usb_exit()\n"); | 1142 | pr_debug("usb_exit()\n"); |
| 1134 | usb_deregister(&driver); | 1143 | usb_deregister(&driver); |
| 1144 | destroy_workqueue(zd_workqueue); | ||
| 1135 | } | 1145 | } |
| 1136 | 1146 | ||
| 1137 | module_init(usb_init); | 1147 | module_init(usb_init); |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index ded39de5f72d..e81a2d3cfffd 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
| @@ -238,4 +238,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
| 238 | 238 | ||
| 239 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); | 239 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); |
| 240 | 240 | ||
| 241 | extern struct workqueue_struct *zd_workqueue; | ||
| 242 | |||
| 241 | #endif /* _ZD_USB_H */ | 243 | #endif /* _ZD_USB_H */ |
