Automatic merge of /spare/repo/netdev-2.6 branch qeth

authored by and committed by Jeff Garzik 8a75e7d6 f5a702b2

+914 -901
+2 -1
drivers/s390/net/Makefile
··· 9 9 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 10 10 obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o 11 11 obj-$(CONFIG_LCS) += lcs.o cu3088.o 12 - qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o 12 + obj-$(CONFIG_CLAW) += claw.o cu3088.o 13 + qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o 13 14 qeth-$(CONFIG_PROC_FS) += qeth_proc.o 14 15 obj-$(CONFIG_QETH) += qeth.o
+8 -4
drivers/s390/net/ctcdbug.h
··· 1 1 /* 2 2 * 3 - * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.4 $) 3 + * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $) 4 4 * 5 5 * CTC / ESCON network driver - s390 dbf exploit. 6 6 * ··· 9 9 * Author(s): Original Code written by 10 10 * Peter Tiedemann (ptiedem@de.ibm.com) 11 11 * 12 - * $Revision: 1.4 $ $Date: 2004/10/15 09:26:58 $ 12 + * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $ 13 13 * 14 14 * This program is free software; you can redistribute it and/or modify 15 15 * it under the terms of the GNU General Public License as published by ··· 25 25 * along with this program; if not, write to the Free Software 26 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 27 */ 28 - 28 + #ifndef _CTCDBUG_H_ 29 + #define _CTCDBUG_H_ 29 30 30 31 #include <asm/debug.h> 32 + #include "ctcmain.h" 31 33 /** 32 34 * Debug Facility stuff 33 35 */ ··· 43 41 #define CTC_DBF_DATA_LEN 128 44 42 #define CTC_DBF_DATA_INDEX 3 45 43 #define CTC_DBF_DATA_NR_AREAS 1 46 - #define CTC_DBF_DATA_LEVEL 2 44 + #define CTC_DBF_DATA_LEVEL 3 47 45 48 46 #define CTC_DBF_TRACE_NAME "ctc_trace" 49 47 #define CTC_DBF_TRACE_LEN 16 ··· 123 121 printk("\n"); 124 122 } 125 123 124 + 125 + #endif
+207 -411
drivers/s390/net/ctcmain.c
··· 1 1 /* 2 - * $Id: ctcmain.c,v 1.72 2005/03/17 10:51:52 ptiedem Exp $ 2 + * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $ 3 3 * 4 4 * CTC / ESCON network driver 5 5 * ··· 37 37 * along with this program; if not, write to the Free Software 38 38 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 39 39 * 40 - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.72 $ 40 + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $ 41 41 * 42 42 */ 43 43 44 44 #undef DEBUG 45 - 46 45 #include <linux/module.h> 47 46 #include <linux/init.h> 48 47 #include <linux/kernel.h> ··· 73 74 #include "ctctty.h" 74 75 #include "fsm.h" 75 76 #include "cu3088.h" 77 + 76 78 #include "ctcdbug.h" 79 + #include "ctcmain.h" 77 80 78 81 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); 79 82 MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver"); 80 83 MODULE_LICENSE("GPL"); 81 - 82 - /** 83 - * CCW commands, used in this driver. 84 - */ 85 - #define CCW_CMD_WRITE 0x01 86 - #define CCW_CMD_READ 0x02 87 - #define CCW_CMD_SET_EXTENDED 0xc3 88 - #define CCW_CMD_PREPARE 0xe3 89 - 90 - #define CTC_PROTO_S390 0 91 - #define CTC_PROTO_LINUX 1 92 - #define CTC_PROTO_LINUX_TTY 2 93 - #define CTC_PROTO_OS390 3 94 - #define CTC_PROTO_MAX 3 95 - 96 - #define CTC_BUFSIZE_LIMIT 65535 97 - #define CTC_BUFSIZE_DEFAULT 32768 98 - 99 - #define CTC_TIMEOUT_5SEC 5000 100 - 101 - #define CTC_INITIAL_BLOCKLEN 2 102 - 103 - #define READ 0 104 - #define WRITE 1 105 - 106 - #define CTC_ID_SIZE BUS_ID_SIZE+3 107 - 108 - 109 - struct ctc_profile { 110 - unsigned long maxmulti; 111 - unsigned long maxcqueue; 112 - unsigned long doios_single; 113 - unsigned long doios_multi; 114 - unsigned long txlen; 115 - unsigned long tx_time; 116 - struct timespec send_stamp; 117 - }; 118 - 119 - /** 120 - * Definition of one channel 121 - */ 122 - struct channel { 123 - 124 - /** 125 - * Pointer to next channel in list. 126 - */ 127 - struct channel *next; 128 - char id[CTC_ID_SIZE]; 129 - struct ccw_device *cdev; 130 - 131 - /** 132 - * Type of this channel. 133 - * CTC/A or Escon for valid channels. 134 - */ 135 - enum channel_types type; 136 - 137 - /** 138 - * Misc. flags. See CHANNEL_FLAGS_... below 139 - */ 140 - __u32 flags; 141 - 142 - /** 143 - * The protocol of this channel 144 - */ 145 - __u16 protocol; 146 - 147 - /** 148 - * I/O and irq related stuff 149 - */ 150 - struct ccw1 *ccw; 151 - struct irb *irb; 152 - 153 - /** 154 - * RX/TX buffer size 155 - */ 156 - int max_bufsize; 157 - 158 - /** 159 - * Transmit/Receive buffer. 160 - */ 161 - struct sk_buff *trans_skb; 162 - 163 - /** 164 - * Universal I/O queue. 165 - */ 166 - struct sk_buff_head io_queue; 167 - 168 - /** 169 - * TX queue for collecting skb's during busy. 170 - */ 171 - struct sk_buff_head collect_queue; 172 - 173 - /** 174 - * Amount of data in collect_queue. 175 - */ 176 - int collect_len; 177 - 178 - /** 179 - * spinlock for collect_queue and collect_len 180 - */ 181 - spinlock_t collect_lock; 182 - 183 - /** 184 - * Timer for detecting unresposive 185 - * I/O operations. 186 - */ 187 - fsm_timer timer; 188 - 189 - /** 190 - * Retry counter for misc. operations. 191 - */ 192 - int retry; 193 - 194 - /** 195 - * The finite state machine of this channel 196 - */ 197 - fsm_instance *fsm; 198 - 199 - /** 200 - * The corresponding net_device this channel 201 - * belongs to. 202 - */ 203 - struct net_device *netdev; 204 - 205 - struct ctc_profile prof; 206 - 207 - unsigned char *trans_skb_data; 208 - 209 - __u16 logflags; 210 - }; 211 - 212 - #define CHANNEL_FLAGS_READ 0 213 - #define CHANNEL_FLAGS_WRITE 1 214 - #define CHANNEL_FLAGS_INUSE 2 215 - #define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 216 - #define CHANNEL_FLAGS_FAILED 8 217 - #define CHANNEL_FLAGS_WAITIRQ 16 218 - #define CHANNEL_FLAGS_RWMASK 1 219 - #define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) 220 - 221 - #define LOG_FLAG_ILLEGALPKT 1 222 - #define LOG_FLAG_ILLEGALSIZE 2 223 - #define LOG_FLAG_OVERRUN 4 224 - #define LOG_FLAG_NOMEM 8 225 - 226 - #define CTC_LOGLEVEL_INFO 1 227 - #define CTC_LOGLEVEL_NOTICE 2 228 - #define CTC_LOGLEVEL_WARN 4 229 - #define CTC_LOGLEVEL_EMERG 8 230 - #define CTC_LOGLEVEL_ERR 16 231 - #define CTC_LOGLEVEL_DEBUG 32 232 - #define CTC_LOGLEVEL_CRIT 64 233 - 234 - #define CTC_LOGLEVEL_DEFAULT \ 235 - (CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT) 236 - 237 - #define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1) 238 - 239 - static int loglevel = CTC_LOGLEVEL_DEFAULT; 240 - 241 - #define ctc_pr_debug(fmt, arg...) \ 242 - do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0) 243 - 244 - #define ctc_pr_info(fmt, arg...) \ 245 - do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0) 246 - 247 - #define ctc_pr_notice(fmt, arg...) \ 248 - do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0) 249 - 250 - #define ctc_pr_warn(fmt, arg...) \ 251 - do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0) 252 - 253 - #define ctc_pr_emerg(fmt, arg...) \ 254 - do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0) 255 - 256 - #define ctc_pr_err(fmt, arg...) \ 257 - do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0) 258 - 259 - #define ctc_pr_crit(fmt, arg...) \ 260 - do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0) 261 - 262 - /** 263 - * Linked list of all detected channels. 264 - */ 265 - static struct channel *channels = NULL; 266 - 267 - struct ctc_priv { 268 - struct net_device_stats stats; 269 - unsigned long tbusy; 270 - /** 271 - * The finite state machine of this interface. 272 - */ 273 - fsm_instance *fsm; 274 - /** 275 - * The protocol of this device 276 - */ 277 - __u16 protocol; 278 - /** 279 - * Timer for restarting after I/O Errors 280 - */ 281 - fsm_timer restart_timer; 282 - 283 - int buffer_size; 284 - 285 - struct channel *channel[2]; 286 - }; 287 - 288 - /** 289 - * Definition of our link level header. 290 - */ 291 - struct ll_header { 292 - __u16 length; 293 - __u16 type; 294 - __u16 unused; 295 - }; 296 - #define LL_HEADER_LENGTH (sizeof(struct ll_header)) 297 - 298 - /** 299 - * Compatibility macros for busy handling 300 - * of network devices. 301 - */ 302 - static __inline__ void 303 - ctc_clear_busy(struct net_device * dev) 304 - { 305 - clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); 306 - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) 307 - netif_wake_queue(dev); 308 - } 309 - 310 - static __inline__ int 311 - ctc_test_and_set_busy(struct net_device * dev) 312 - { 313 - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) 314 - netif_stop_queue(dev); 315 - return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); 316 - } 317 - 318 - /** 319 - * Print Banner. 320 - */ 321 - static void 322 - print_banner(void) 323 - { 324 - static int printed = 0; 325 - char vbuf[] = "$Revision: 1.72 $"; 326 - char *version = vbuf; 327 - 328 - if (printed) 329 - return; 330 - if ((version = strchr(version, ':'))) { 331 - char *p = strchr(version + 1, '$'); 332 - if (p) 333 - *p = '\0'; 334 - } else 335 - version = " ??? "; 336 - printk(KERN_INFO "CTC driver Version%s" 337 - #ifdef DEBUG 338 - " (DEBUG-VERSION, " __DATE__ __TIME__ ")" 339 - #endif 340 - " initialized\n", version); 341 - printed = 1; 342 - } 343 - 344 - /** 345 - * Return type of a detected device. 346 - */ 347 - static enum channel_types 348 - get_channel_type(struct ccw_device_id *id) 349 - { 350 - enum channel_types type = (enum channel_types) id->driver_info; 351 - 352 - if (type == channel_type_ficon) 353 - type = channel_type_escon; 354 - 355 - return type; 356 - } 357 - 358 84 /** 359 85 * States of the interface statemachine. 360 86 */ ··· 95 371 /** 96 372 * MUST be always the last element!! 97 373 */ 98 - NR_DEV_STATES 374 + CTC_NR_DEV_STATES 99 375 }; 100 376 101 377 static const char *dev_state_names[] = { ··· 123 399 /** 124 400 * MUST be always the last element!! 125 401 */ 126 - NR_DEV_EVENTS 402 + CTC_NR_DEV_EVENTS 127 403 }; 128 404 129 405 static const char *dev_event_names[] = { ··· 200 476 NR_CH_EVENTS, 201 477 }; 202 478 203 - static const char *ch_event_names[] = { 204 - "ccw_device success", 205 - "ccw_device busy", 206 - "ccw_device enodev", 207 - "ccw_device ioerr", 208 - "ccw_device unknown", 209 - 210 - "Status ATTN & BUSY", 211 - "Status ATTN", 212 - "Status BUSY", 213 - 214 - "Unit check remote reset", 215 - "Unit check remote system reset", 216 - "Unit check TX timeout", 217 - "Unit check TX parity", 218 - "Unit check Hardware failure", 219 - "Unit check RX parity", 220 - "Unit check ZERO", 221 - "Unit check Unknown", 222 - 223 - "SubChannel check Unknown", 224 - 225 - "Machine check failure", 226 - "Machine check operational", 227 - 228 - "IRQ normal", 229 - "IRQ final", 230 - 231 - "Timer", 232 - 233 - "Start", 234 - "Stop", 235 - }; 236 - 237 479 /** 238 480 * States of the channel statemachine. 239 481 */ ··· 233 543 * MUST be always the last element!! 234 544 */ 235 545 NR_CH_STATES, 546 + }; 547 + 548 + static int loglevel = CTC_LOGLEVEL_DEFAULT; 549 + 550 + /** 551 + * Linked list of all detected channels. 552 + */ 553 + static struct channel *channels = NULL; 554 + 555 + /** 556 + * Print Banner. 557 + */ 558 + static void 559 + print_banner(void) 560 + { 561 + static int printed = 0; 562 + char vbuf[] = "$Revision: 1.74 $"; 563 + char *version = vbuf; 564 + 565 + if (printed) 566 + return; 567 + if ((version = strchr(version, ':'))) { 568 + char *p = strchr(version + 1, '$'); 569 + if (p) 570 + *p = '\0'; 571 + } else 572 + version = " ??? "; 573 + printk(KERN_INFO "CTC driver Version%s" 574 + #ifdef DEBUG 575 + " (DEBUG-VERSION, " __DATE__ __TIME__ ")" 576 + #endif 577 + " initialized\n", version); 578 + printed = 1; 579 + } 580 + 581 + /** 582 + * Return type of a detected device. 583 + */ 584 + static enum channel_types 585 + get_channel_type(struct ccw_device_id *id) 586 + { 587 + enum channel_types type = (enum channel_types) id->driver_info; 588 + 589 + if (type == channel_type_ficon) 590 + type = channel_type_escon; 591 + 592 + return type; 593 + } 594 + 595 + static const char *ch_event_names[] = { 596 + "ccw_device success", 597 + "ccw_device busy", 598 + "ccw_device enodev", 599 + "ccw_device ioerr", 600 + "ccw_device unknown", 601 + 602 + "Status ATTN & BUSY", 603 + "Status ATTN", 604 + "Status BUSY", 605 + 606 + "Unit check remote reset", 607 + "Unit check remote system reset", 608 + "Unit check TX timeout", 609 + "Unit check TX parity", 610 + "Unit check Hardware failure", 611 + "Unit check RX parity", 612 + "Unit check ZERO", 613 + "Unit check Unknown", 614 + 615 + "SubChannel check Unknown", 616 + 617 + "Machine check failure", 618 + "Machine check operational", 619 + 620 + "IRQ normal", 621 + "IRQ final", 622 + 623 + "Timer", 624 + 625 + "Start", 626 + "Stop", 236 627 }; 237 628 238 629 static const char *ch_state_names[] = { ··· 1705 1934 ch->cdev = cdev; 1706 1935 snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id); 1707 1936 ch->type = type; 1708 - loglevel = CTC_LOGLEVEL_DEFAULT; 1709 1937 ch->fsm = init_fsm(ch->id, ch_state_names, 1710 1938 ch_event_names, NR_CH_STATES, NR_CH_EVENTS, 1711 1939 ch_fsm, CH_FSM_LEN, GFP_KERNEL); ··· 2467 2697 /* 2468 2698 * sysfs attributes 2469 2699 */ 2700 + 2470 2701 static ssize_t 2471 2702 buffer_show(struct device *dev, char *buf) 2472 2703 { ··· 2486 2715 struct ctc_priv *priv; 2487 2716 struct net_device *ndev; 2488 2717 int bs1; 2718 + char buffer[16]; 2489 2719 2490 2720 DBF_TEXT(trace, 3, __FUNCTION__); 2721 + DBF_TEXT(trace, 3, buf); 2491 2722 priv = dev->driver_data; 2492 - if (!priv) 2723 + if (!priv) { 2724 + DBF_TEXT(trace, 3, "bfnopriv"); 2493 2725 return -ENODEV; 2494 - ndev = priv->channel[READ]->netdev; 2495 - if (!ndev) 2496 - return -ENODEV; 2497 - sscanf(buf, "%u", &bs1); 2726 + } 2498 2727 2728 + sscanf(buf, "%u", &bs1); 2499 2729 if (bs1 > CTC_BUFSIZE_LIMIT) 2500 - return -EINVAL; 2730 + goto einval; 2731 + if (bs1 < (576 + LL_HEADER_LENGTH + 2)) 2732 + goto einval; 2733 + priv->buffer_size = bs1; // just to overwrite the default 2734 + 2735 + ndev = priv->channel[READ]->netdev; 2736 + if (!ndev) { 2737 + DBF_TEXT(trace, 3, "bfnondev"); 2738 + return -ENODEV; 2739 + } 2740 + 2501 2741 if ((ndev->flags & IFF_RUNNING) && 2502 2742 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2))) 2503 - return -EINVAL; 2504 - if (bs1 < (576 + LL_HEADER_LENGTH + 2)) 2505 - return -EINVAL; 2743 + goto einval; 2506 2744 2507 - priv->buffer_size = bs1; 2508 - priv->channel[READ]->max_bufsize = 2509 - priv->channel[WRITE]->max_bufsize = bs1; 2745 + priv->channel[READ]->max_bufsize = bs1; 2746 + priv->channel[WRITE]->max_bufsize = bs1; 2510 2747 if (!(ndev->flags & IFF_RUNNING)) 2511 2748 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2; 2512 2749 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 2513 2750 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 2514 2751 2752 + sprintf(buffer, "%d",priv->buffer_size); 2753 + DBF_TEXT(trace, 3, buffer); 2515 2754 return count; 2516 2755 2756 + einval: 2757 + DBF_TEXT(trace, 3, "buff_err"); 2758 + return -EINVAL; 2517 2759 } 2518 2760 2519 2761 static ssize_t 2520 2762 loglevel_show(struct device *dev, char *buf) 2521 2763 { 2522 - struct ctc_priv *priv; 2523 - 2524 - priv = dev->driver_data; 2525 - if (!priv) 2526 - return -ENODEV; 2527 2764 return sprintf(buf, "%d\n", loglevel); 2528 2765 } 2529 2766 2530 2767 static ssize_t 2531 2768 loglevel_write(struct device *dev, const char *buf, size_t count) 2532 2769 { 2533 - struct ctc_priv *priv; 2534 2770 int ll1; 2535 2771 2536 2772 DBF_TEXT(trace, 5, __FUNCTION__); 2537 - priv = dev->driver_data; 2538 - if (!priv) 2539 - return -ENODEV; 2540 2773 sscanf(buf, "%i", &ll1); 2541 2774 2542 2775 if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0)) ··· 2610 2835 return count; 2611 2836 } 2612 2837 2613 - static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); 2614 - static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write); 2615 - static DEVICE_ATTR(stats, 0644, stats_show, stats_write); 2616 - 2617 - static int 2618 - ctc_add_attributes(struct device *dev) 2619 - { 2620 - // device_create_file(dev, &dev_attr_buffer); 2621 - device_create_file(dev, &dev_attr_loglevel); 2622 - device_create_file(dev, &dev_attr_stats); 2623 - return 0; 2624 - } 2625 - 2626 - static void 2627 - ctc_remove_attributes(struct device *dev) 2628 - { 2629 - device_remove_file(dev, &dev_attr_stats); 2630 - device_remove_file(dev, &dev_attr_loglevel); 2631 - // device_remove_file(dev, &dev_attr_buffer); 2632 - } 2633 - 2634 2838 2635 2839 static void 2636 2840 ctc_netdev_unregister(struct net_device * dev) ··· 2653 2899 #endif 2654 2900 } 2655 2901 2656 - /** 2657 - * Initialize everything of the net device except the name and the 2658 - * channel structs. 2659 - */ 2660 - static struct net_device * 2661 - ctc_init_netdevice(struct net_device * dev, int alloc_device, 2662 - struct ctc_priv *privptr) 2663 - { 2664 - if (!privptr) 2665 - return NULL; 2666 - 2667 - DBF_TEXT(setup, 3, __FUNCTION__); 2668 - if (alloc_device) { 2669 - dev = kmalloc(sizeof (struct net_device), GFP_KERNEL); 2670 - if (!dev) 2671 - return NULL; 2672 - memset(dev, 0, sizeof (struct net_device)); 2673 - } 2674 - 2675 - dev->priv = privptr; 2676 - privptr->fsm = init_fsm("ctcdev", dev_state_names, 2677 - dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, 2678 - dev_fsm, DEV_FSM_LEN, GFP_KERNEL); 2679 - if (privptr->fsm == NULL) { 2680 - if (alloc_device) 2681 - kfree(dev); 2682 - return NULL; 2683 - } 2684 - fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); 2685 - fsm_settimer(privptr->fsm, &privptr->restart_timer); 2686 - if (dev->mtu == 0) 2687 - dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; 2688 - dev->hard_start_xmit = ctc_tx; 2689 - dev->open = ctc_open; 2690 - dev->stop = ctc_close; 2691 - dev->get_stats = ctc_stats; 2692 - dev->change_mtu = ctc_change_mtu; 2693 - dev->hard_header_len = LL_HEADER_LENGTH + 2; 2694 - dev->addr_len = 0; 2695 - dev->type = ARPHRD_SLIP; 2696 - dev->tx_queue_len = 100; 2697 - dev->flags = IFF_POINTOPOINT | IFF_NOARP; 2698 - SET_MODULE_OWNER(dev); 2699 - return dev; 2700 - } 2701 - 2702 2902 static ssize_t 2703 2903 ctc_proto_show(struct device *dev, char *buf) 2704 2904 { ··· 2685 2977 return count; 2686 2978 } 2687 2979 2688 - static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store); 2689 2980 2690 2981 static ssize_t 2691 2982 ctc_type_show(struct device *dev, char *buf) ··· 2698 2991 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); 2699 2992 } 2700 2993 2994 + static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); 2995 + static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store); 2701 2996 static DEVICE_ATTR(type, 0444, ctc_type_show, NULL); 2997 + 2998 + static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write); 2999 + static DEVICE_ATTR(stats, 0644, stats_show, stats_write); 2702 3000 2703 3001 static struct attribute *ctc_attr[] = { 2704 3002 &dev_attr_protocol.attr, ··· 2715 3003 static struct attribute_group ctc_attr_group = { 2716 3004 .attrs = ctc_attr, 2717 3005 }; 3006 + 3007 + static int 3008 + ctc_add_attributes(struct device *dev) 3009 + { 3010 + device_create_file(dev, &dev_attr_loglevel); 3011 + device_create_file(dev, &dev_attr_stats); 3012 + return 0; 3013 + } 3014 + 3015 + static void 3016 + ctc_remove_attributes(struct device *dev) 3017 + { 3018 + device_remove_file(dev, &dev_attr_stats); 3019 + device_remove_file(dev, &dev_attr_loglevel); 3020 + } 2718 3021 2719 3022 static int 2720 3023 ctc_add_files(struct device *dev) ··· 2755 3028 * 2756 3029 * @returns 0 on success, !0 on failure. 2757 3030 */ 2758 - 2759 3031 static int 2760 3032 ctc_probe_device(struct ccwgroup_device *cgdev) 2761 3033 { 2762 3034 struct ctc_priv *priv; 2763 3035 int rc; 3036 + char buffer[16]; 2764 3037 2765 3038 pr_debug("%s() called\n", __FUNCTION__); 2766 - DBF_TEXT(trace, 3, __FUNCTION__); 3039 + DBF_TEXT(setup, 3, __FUNCTION__); 2767 3040 2768 3041 if (!get_device(&cgdev->dev)) 2769 3042 return -ENODEV; ··· 2787 3060 cgdev->cdev[1]->handler = ctc_irq_handler; 2788 3061 cgdev->dev.driver_data = priv; 2789 3062 3063 + sprintf(buffer, "%p", priv); 3064 + DBF_TEXT(data, 3, buffer); 3065 + 3066 + sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv)); 3067 + DBF_TEXT(data, 3, buffer); 3068 + 3069 + sprintf(buffer, "%p", &channels); 3070 + DBF_TEXT(data, 3, buffer); 3071 + 3072 + sprintf(buffer, "%u", (unsigned int)sizeof(struct channel)); 3073 + DBF_TEXT(data, 3, buffer); 3074 + 2790 3075 return 0; 2791 3076 } 3077 + 3078 + /** 3079 + * Initialize everything of the net device except the name and the 3080 + * channel structs. 3081 + */ 3082 + static struct net_device * 3083 + ctc_init_netdevice(struct net_device * dev, int alloc_device, 3084 + struct ctc_priv *privptr) 3085 + { 3086 + if (!privptr) 3087 + return NULL; 3088 + 3089 + DBF_TEXT(setup, 3, __FUNCTION__); 3090 + 3091 + if (alloc_device) { 3092 + dev = kmalloc(sizeof (struct net_device), GFP_KERNEL); 3093 + if (!dev) 3094 + return NULL; 3095 + memset(dev, 0, sizeof (struct net_device)); 3096 + } 3097 + 3098 + dev->priv = privptr; 3099 + privptr->fsm = init_fsm("ctcdev", dev_state_names, 3100 + dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS, 3101 + dev_fsm, DEV_FSM_LEN, GFP_KERNEL); 3102 + if (privptr->fsm == NULL) { 3103 + if (alloc_device) 3104 + kfree(dev); 3105 + return NULL; 3106 + } 3107 + fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); 3108 + fsm_settimer(privptr->fsm, &privptr->restart_timer); 3109 + if (dev->mtu == 0) 3110 + dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; 3111 + dev->hard_start_xmit = ctc_tx; 3112 + dev->open = ctc_open; 3113 + dev->stop = ctc_close; 3114 + dev->get_stats = ctc_stats; 3115 + dev->change_mtu = ctc_change_mtu; 3116 + dev->hard_header_len = LL_HEADER_LENGTH + 2; 3117 + dev->addr_len = 0; 3118 + dev->type = ARPHRD_SLIP; 3119 + dev->tx_queue_len = 100; 3120 + dev->flags = IFF_POINTOPOINT | IFF_NOARP; 3121 + SET_MODULE_OWNER(dev); 3122 + return dev; 3123 + } 3124 + 2792 3125 2793 3126 /** 2794 3127 * ··· 2868 3081 struct ctc_priv *privptr; 2869 3082 struct net_device *dev; 2870 3083 int ret; 3084 + char buffer[16]; 2871 3085 2872 3086 pr_debug("%s() called\n", __FUNCTION__); 2873 3087 DBF_TEXT(setup, 3, __FUNCTION__); ··· 2876 3088 privptr = cgdev->dev.driver_data; 2877 3089 if (!privptr) 2878 3090 return -ENODEV; 3091 + 3092 + sprintf(buffer, "%d", privptr->buffer_size); 3093 + DBF_TEXT(setup, 3, buffer); 2879 3094 2880 3095 type = get_channel_type(&cgdev->cdev[0]->id); 2881 3096 ··· 2968 3177 struct ctc_priv *priv; 2969 3178 struct net_device *ndev; 2970 3179 2971 - DBF_TEXT(trace, 3, __FUNCTION__); 3180 + DBF_TEXT(setup, 3, __FUNCTION__); 2972 3181 pr_debug("%s() called\n", __FUNCTION__); 3182 + 2973 3183 2974 3184 priv = cgdev->dev.driver_data; 2975 3185 ndev = NULL; ··· 3007 3215 channel_remove(priv->channel[READ]); 3008 3216 if (priv->channel[WRITE]) 3009 3217 channel_remove(priv->channel[WRITE]); 3010 - 3011 3218 priv->channel[READ] = priv->channel[WRITE] = NULL; 3012 3219 3013 3220 return 0; ··· 3019 3228 struct ctc_priv *priv; 3020 3229 3021 3230 pr_debug("%s() called\n", __FUNCTION__); 3022 - DBF_TEXT(trace, 3, __FUNCTION__); 3231 + DBF_TEXT(setup, 3, __FUNCTION__); 3023 3232 3024 3233 priv = cgdev->dev.driver_data; 3025 3234 if (!priv) ··· 3056 3265 static void __exit 3057 3266 ctc_exit(void) 3058 3267 { 3268 + DBF_TEXT(setup, 3, __FUNCTION__); 3059 3269 unregister_cu3088_discipline(&ctc_group_driver); 3060 3270 ctc_tty_cleanup(); 3061 3271 ctc_unregister_dbf_views(); ··· 3073 3281 ctc_init(void) 3074 3282 { 3075 3283 int ret = 0; 3284 + 3285 + loglevel = CTC_LOGLEVEL_DEFAULT; 3286 + 3287 + DBF_TEXT(setup, 3, __FUNCTION__); 3076 3288 3077 3289 print_banner(); 3078 3290
+276
drivers/s390/net/ctcmain.h
··· 1 + /* 2 + * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $ 3 + * 4 + * CTC / ESCON network driver 5 + * 6 + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 + * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) 8 + Peter Tiedemann (ptiedem@de.ibm.com) 9 + * 10 + * 11 + * Documentation used: 12 + * - Principles of Operation (IBM doc#: SA22-7201-06) 13 + * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02) 14 + * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535) 15 + * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00) 16 + * - ESCON I/O Interface (IBM doc#: SA22-7202-029 17 + * 18 + * This program is free software; you can redistribute it and/or modify 19 + * it under the terms of the GNU General Public License as published by 20 + * the Free Software Foundation; either version 2, or (at your option) 21 + * any later version. 22 + * 23 + * This program is distributed in the hope that it will be useful, 24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 + * GNU General Public License for more details. 27 + * 28 + * You should have received a copy of the GNU General Public License 29 + * along with this program; if not, write to the Free Software 30 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31 + * 32 + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $ 33 + * 34 + */ 35 + 36 + #ifndef _CTCMAIN_H_ 37 + #define _CTCMAIN_H_ 38 + 39 + #include <asm/ccwdev.h> 40 + #include <asm/ccwgroup.h> 41 + 42 + #include "ctctty.h" 43 + #include "fsm.h" 44 + #include "cu3088.h" 45 + 46 + 47 + /** 48 + * CCW commands, used in this driver. 49 + */ 50 + #define CCW_CMD_WRITE 0x01 51 + #define CCW_CMD_READ 0x02 52 + #define CCW_CMD_SET_EXTENDED 0xc3 53 + #define CCW_CMD_PREPARE 0xe3 54 + 55 + #define CTC_PROTO_S390 0 56 + #define CTC_PROTO_LINUX 1 57 + #define CTC_PROTO_LINUX_TTY 2 58 + #define CTC_PROTO_OS390 3 59 + #define CTC_PROTO_MAX 3 60 + 61 + #define CTC_BUFSIZE_LIMIT 65535 62 + #define CTC_BUFSIZE_DEFAULT 32768 63 + 64 + #define CTC_TIMEOUT_5SEC 5000 65 + 66 + #define CTC_INITIAL_BLOCKLEN 2 67 + 68 + #define READ 0 69 + #define WRITE 1 70 + 71 + #define CTC_ID_SIZE BUS_ID_SIZE+3 72 + 73 + 74 + struct ctc_profile { 75 + unsigned long maxmulti; 76 + unsigned long maxcqueue; 77 + unsigned long doios_single; 78 + unsigned long doios_multi; 79 + unsigned long txlen; 80 + unsigned long tx_time; 81 + struct timespec send_stamp; 82 + }; 83 + 84 + /** 85 + * Definition of one channel 86 + */ 87 + struct channel { 88 + 89 + /** 90 + * Pointer to next channel in list. 91 + */ 92 + struct channel *next; 93 + char id[CTC_ID_SIZE]; 94 + struct ccw_device *cdev; 95 + 96 + /** 97 + * Type of this channel. 98 + * CTC/A or Escon for valid channels. 99 + */ 100 + enum channel_types type; 101 + 102 + /** 103 + * Misc. flags. See CHANNEL_FLAGS_... below 104 + */ 105 + __u32 flags; 106 + 107 + /** 108 + * The protocol of this channel 109 + */ 110 + __u16 protocol; 111 + 112 + /** 113 + * I/O and irq related stuff 114 + */ 115 + struct ccw1 *ccw; 116 + struct irb *irb; 117 + 118 + /** 119 + * RX/TX buffer size 120 + */ 121 + int max_bufsize; 122 + 123 + /** 124 + * Transmit/Receive buffer. 125 + */ 126 + struct sk_buff *trans_skb; 127 + 128 + /** 129 + * Universal I/O queue. 130 + */ 131 + struct sk_buff_head io_queue; 132 + 133 + /** 134 + * TX queue for collecting skb's during busy. 135 + */ 136 + struct sk_buff_head collect_queue; 137 + 138 + /** 139 + * Amount of data in collect_queue. 140 + */ 141 + int collect_len; 142 + 143 + /** 144 + * spinlock for collect_queue and collect_len 145 + */ 146 + spinlock_t collect_lock; 147 + 148 + /** 149 + * Timer for detecting unresposive 150 + * I/O operations. 151 + */ 152 + fsm_timer timer; 153 + 154 + /** 155 + * Retry counter for misc. operations. 156 + */ 157 + int retry; 158 + 159 + /** 160 + * The finite state machine of this channel 161 + */ 162 + fsm_instance *fsm; 163 + 164 + /** 165 + * The corresponding net_device this channel 166 + * belongs to. 167 + */ 168 + struct net_device *netdev; 169 + 170 + struct ctc_profile prof; 171 + 172 + unsigned char *trans_skb_data; 173 + 174 + __u16 logflags; 175 + }; 176 + 177 + #define CHANNEL_FLAGS_READ 0 178 + #define CHANNEL_FLAGS_WRITE 1 179 + #define CHANNEL_FLAGS_INUSE 2 180 + #define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 181 + #define CHANNEL_FLAGS_FAILED 8 182 + #define CHANNEL_FLAGS_WAITIRQ 16 183 + #define CHANNEL_FLAGS_RWMASK 1 184 + #define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) 185 + 186 + #define LOG_FLAG_ILLEGALPKT 1 187 + #define LOG_FLAG_ILLEGALSIZE 2 188 + #define LOG_FLAG_OVERRUN 4 189 + #define LOG_FLAG_NOMEM 8 190 + 191 + #define CTC_LOGLEVEL_INFO 1 192 + #define CTC_LOGLEVEL_NOTICE 2 193 + #define CTC_LOGLEVEL_WARN 4 194 + #define CTC_LOGLEVEL_EMERG 8 195 + #define CTC_LOGLEVEL_ERR 16 196 + #define CTC_LOGLEVEL_DEBUG 32 197 + #define CTC_LOGLEVEL_CRIT 64 198 + 199 + #define CTC_LOGLEVEL_DEFAULT \ 200 + (CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT) 201 + 202 + #define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1) 203 + 204 + #define ctc_pr_debug(fmt, arg...) \ 205 + do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0) 206 + 207 + #define ctc_pr_info(fmt, arg...) \ 208 + do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0) 209 + 210 + #define ctc_pr_notice(fmt, arg...) \ 211 + do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0) 212 + 213 + #define ctc_pr_warn(fmt, arg...) \ 214 + do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0) 215 + 216 + #define ctc_pr_emerg(fmt, arg...) \ 217 + do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0) 218 + 219 + #define ctc_pr_err(fmt, arg...) \ 220 + do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0) 221 + 222 + #define ctc_pr_crit(fmt, arg...) \ 223 + do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0) 224 + 225 + struct ctc_priv { 226 + struct net_device_stats stats; 227 + unsigned long tbusy; 228 + /** 229 + * The finite state machine of this interface. 230 + */ 231 + fsm_instance *fsm; 232 + /** 233 + * The protocol of this device 234 + */ 235 + __u16 protocol; 236 + /** 237 + * Timer for restarting after I/O Errors 238 + */ 239 + fsm_timer restart_timer; 240 + 241 + int buffer_size; 242 + 243 + struct channel *channel[2]; 244 + }; 245 + 246 + /** 247 + * Definition of our link level header. 248 + */ 249 + struct ll_header { 250 + __u16 length; 251 + __u16 type; 252 + __u16 unused; 253 + }; 254 + #define LL_HEADER_LENGTH (sizeof(struct ll_header)) 255 + 256 + /** 257 + * Compatibility macros for busy handling 258 + * of network devices. 259 + */ 260 + static __inline__ void 261 + ctc_clear_busy(struct net_device * dev) 262 + { 263 + clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); 264 + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) 265 + netif_wake_queue(dev); 266 + } 267 + 268 + static __inline__ int 269 + ctc_test_and_set_busy(struct net_device * dev) 270 + { 271 + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) 272 + netif_stop_queue(dev); 273 + return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); 274 + } 275 + 276 + #endif
+2 -3
drivers/s390/net/ctctty.c
··· 1 1 /* 2 - * $Id: ctctty.c,v 1.26 2004/08/04 11:06:55 mschwide Exp $ 2 + * $Id: ctctty.c,v 1.29 2005/04/05 08:50:44 mschwide Exp $ 3 3 * 4 4 * CTC / ESCON network driver, tty interface. 5 5 * ··· 1056 1056 info->tty = 0; 1057 1057 tty->closing = 0; 1058 1058 if (info->blocked_open) { 1059 - set_current_state(TASK_INTERRUPTIBLE); 1060 - schedule_timeout(HZ/2); 1059 + msleep_interruptible(500); 1061 1060 wake_up_interruptible(&info->open_wait); 1062 1061 } 1063 1062 info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
+3 -1
drivers/s390/net/cu3088.c
··· 1 1 /* 2 - * $Id: cu3088.c,v 1.34 2004/06/15 13:16:27 pavlic Exp $ 2 + * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $ 3 3 * 4 4 * CTC / LCS ccw_device driver 5 5 * ··· 39 39 "FICON channel", 40 40 "P390 LCS card", 41 41 "OSA LCS card", 42 + "CLAW channel device", 42 43 "unknown channel type", 43 44 "unsupported channel type", 44 45 }; ··· 52 51 { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, 53 52 { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 }, 54 53 { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, 54 + { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw }, 55 55 { /* end of list */ } 56 56 }; 57 57
+3
drivers/s390/net/cu3088.h
··· 23 23 /* Device is a OSA2 card */ 24 24 channel_type_osa2, 25 25 26 + /* Device is a CLAW channel device */ 27 + channel_type_claw, 28 + 26 29 /* Device is a channel, but we don't know 27 30 * anything about it */ 28 31 channel_type_unknown,
+5 -5
drivers/s390/net/iucv.c
··· 1 1 /* 2 - * $Id: iucv.c,v 1.43 2005/02/09 14:47:43 braunu Exp $ 2 + * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $ 3 3 * 4 4 * IUCV network driver 5 5 * ··· 29 29 * along with this program; if not, write to the Free Software 30 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31 31 * 32 - * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.43 $ 32 + * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.45 $ 33 33 * 34 34 */ 35 35 ··· 355 355 static void 356 356 iucv_banner(void) 357 357 { 358 - char vbuf[] = "$Revision: 1.43 $"; 358 + char vbuf[] = "$Revision: 1.45 $"; 359 359 char *version = vbuf; 360 360 361 361 if ((version = strchr(version, ':'))) { ··· 2553 2553 #endif 2554 2554 EXPORT_SYMBOL (iucv_reply_prmmsg); 2555 2555 EXPORT_SYMBOL (iucv_send); 2556 - #if 0 2557 2556 EXPORT_SYMBOL (iucv_send2way); 2558 2557 EXPORT_SYMBOL (iucv_send2way_array); 2559 - EXPORT_SYMBOL (iucv_send_array); 2560 2558 EXPORT_SYMBOL (iucv_send2way_prmmsg); 2561 2559 EXPORT_SYMBOL (iucv_send2way_prmmsg_array); 2560 + #if 0 2561 + EXPORT_SYMBOL (iucv_send_array); 2562 2562 EXPORT_SYMBOL (iucv_send_prmmsg); 2563 2563 EXPORT_SYMBOL (iucv_setmask); 2564 2564 #endif
+17 -16
drivers/s390/net/lcs.c
··· 11 11 * Frank Pavlic (pavlic@de.ibm.com) and 12 12 * Martin Schwidefsky <schwidefsky@de.ibm.com> 13 13 * 14 - * $Revision: 1.96 $ $Date: 2004/11/11 13:42:33 $ 14 + * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $ 15 15 * 16 16 * This program is free software; you can redistribute it and/or modify 17 17 * it under the terms of the GNU General Public License as published by ··· 59 59 /** 60 60 * initialization string for output 61 61 */ 62 - #define VERSION_LCS_C "$Revision: 1.96 $" 62 + #define VERSION_LCS_C "$Revision: 1.98 $" 63 63 64 64 static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; 65 65 static char debug_buffer[255]; ··· 1098 1098 PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n"); 1099 1099 return -EOPNOTSUPP; 1100 1100 } 1101 - /* Print out supported assists: IPv6 */ 1102 - PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name, 1103 - (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ? 1104 - "with" : "without"); 1105 - /* Print out supported assist: Multicast */ 1106 - PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name, 1107 - (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ? 1108 - "with" : "without"); 1109 1101 if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) 1110 1102 return 0; 1111 1103 return -EOPNOTSUPP; ··· 1152 1160 } 1153 1161 } 1154 1162 /* re-insert all entries from the failed_list into ipm_list */ 1155 - list_for_each_entry(ipm, &failed_list, list) { 1163 + list_for_each_entry_safe(ipm, tmp, &failed_list, list) { 1156 1164 list_del_init(&ipm->list); 1157 1165 list_add_tail(&ipm->list, &card->ipm_list); 1158 1166 } ··· 2190 2198 if (!dev) 2191 2199 goto out; 2192 2200 card->dev = dev; 2193 - netdev_out: 2194 2201 card->dev->priv = card; 2195 2202 card->dev->open = lcs_open_device; 2196 2203 card->dev->stop = lcs_stop_device; 2197 2204 card->dev->hard_start_xmit = lcs_start_xmit; 2198 2205 card->dev->get_stats = lcs_getstats; 2199 2206 SET_MODULE_OWNER(dev); 2200 - if (lcs_register_netdev(ccwgdev) != 0) 2201 - goto out; 2202 2207 memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); 2203 2208 #ifdef CONFIG_IP_MULTICAST 2204 2209 if (!lcs_check_multicast_support(card)) 2205 2210 card->dev->set_multicast_list = lcs_set_multicast_list; 2206 2211 #endif 2207 - netif_stop_queue(card->dev); 2212 + netdev_out: 2208 2213 lcs_set_allowed_threads(card,0xffffffff); 2209 2214 if (recover_state == DEV_STATE_RECOVER) { 2210 2215 lcs_set_multicast_list(card->dev); 2211 2216 card->dev->flags |= IFF_UP; 2212 2217 netif_wake_queue(card->dev); 2213 2218 card->state = DEV_STATE_UP; 2214 - } else 2219 + } else { 2215 2220 lcs_stopcard(card); 2221 + } 2216 2222 2223 + if (lcs_register_netdev(ccwgdev) != 0) 2224 + goto out; 2225 + 2226 + /* Print out supported assists: IPv6 */ 2227 + PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name, 2228 + (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ? 2229 + "with" : "without"); 2230 + /* Print out supported assist: Multicast */ 2231 + PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name, 2232 + (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ? 2233 + "with" : "without"); 2217 2234 return 0; 2218 2235 out: 2219 2236
+28 -7
drivers/s390/net/qeth.h
··· 24 24 25 25 #include "qeth_mpc.h" 26 26 27 - #define VERSION_QETH_H "$Revision: 1.135 $" 27 + #define VERSION_QETH_H "$Revision: 1.139 $" 28 28 29 29 #ifdef CONFIG_QETH_IPV6 30 30 #define QETH_VERSION_IPV6 ":IPv6" ··· 288 288 #define QETH_TX_TIMEOUT 100 * HZ 289 289 #define QETH_HEADER_SIZE 32 290 290 #define MAX_PORTNO 15 291 - #define QETH_FAKE_LL_LEN ETH_HLEN 291 + #define QETH_FAKE_LL_LEN_ETH ETH_HLEN 292 + #define QETH_FAKE_LL_LEN_TR (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc)) 292 293 #define QETH_FAKE_LL_V6_ADDR_POS 24 293 294 294 295 /*IPv6 address autoconfiguration stuff*/ ··· 368 367 struct qeth_hdr_layer2 l2; 369 368 struct qeth_hdr_layer3 l3; 370 369 } hdr; 370 + } __attribute__ ((packed)); 371 + 372 + /*TCP Segmentation Offload header*/ 373 + struct qeth_hdr_ext_tso { 374 + __u16 hdr_tot_len; 375 + __u8 imb_hdr_no; 376 + __u8 reserved; 377 + __u8 hdr_type; 378 + __u8 hdr_version; 379 + __u16 hdr_len; 380 + __u32 payload_len; 381 + __u16 mss; 382 + __u16 dg_hdr_len; 383 + __u8 padding[16]; 384 + } __attribute__ ((packed)); 385 + 386 + struct qeth_hdr_tso { 387 + struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ 388 + struct qeth_hdr_ext_tso ext; 371 389 } __attribute__ ((packed)); 372 390 373 391 ··· 886 866 return hdr; 887 867 } 888 868 869 + 889 870 inline static int 890 871 qeth_get_hlen(__u8 link_type) 891 872 { ··· 894 873 switch (link_type) { 895 874 case QETH_LINK_TYPE_HSTR: 896 875 case QETH_LINK_TYPE_LANE_TR: 897 - return sizeof(struct qeth_hdr) + TR_HLEN; 876 + return sizeof(struct qeth_hdr_tso) + TR_HLEN; 898 877 default: 899 878 #ifdef CONFIG_QETH_VLAN 900 - return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN; 879 + return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN; 901 880 #else 902 - return sizeof(struct qeth_hdr) + ETH_HLEN; 881 + return sizeof(struct qeth_hdr_tso) + ETH_HLEN; 903 882 #endif 904 883 } 905 884 #else /* CONFIG_QETH_IPV6 */ 906 885 #ifdef CONFIG_QETH_VLAN 907 - return sizeof(struct qeth_hdr) + VLAN_HLEN; 886 + return sizeof(struct qeth_hdr_tso) + VLAN_HLEN; 908 887 #else 909 - return sizeof(struct qeth_hdr); 888 + return sizeof(struct qeth_hdr_tso); 910 889 #endif 911 890 #endif /* CONFIG_QETH_IPV6 */ 912 891 }
+20 -31
drivers/s390/net/qeth_eddp.c
··· 1 1 /* 2 2 * 3 - * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.11 $) 3 + * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.13 $) 4 4 * 5 5 * Enhanced Device Driver Packing (EDDP) support for the qeth driver. 6 6 * ··· 8 8 * 9 9 * Author(s): Thomas Spatzier <tspat@de.ibm.com> 10 10 * 11 - * $Revision: 1.11 $ $Date: 2005/03/24 09:04:18 $ 11 + * $Revision: 1.13 $ $Date: 2005/05/04 20:19:18 $ 12 12 * 13 13 */ 14 14 #include <linux/config.h> ··· 85 85 qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf) 86 86 { 87 87 struct qeth_eddp_context_reference *ref; 88 - 88 + 89 89 QETH_DBF_TEXT(trace, 6, "eddprctx"); 90 90 while (!list_empty(&buf->ctx_list)){ 91 91 ref = list_entry(buf->ctx_list.next, ··· 139 139 "buffer!\n"); 140 140 goto out; 141 141 } 142 - } 142 + } 143 143 /* check if the whole next skb fits into current buffer */ 144 144 if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) - 145 145 buf->next_element_to_fill) ··· 152 152 * and increment ctx's refcnt */ 153 153 must_refcnt = 1; 154 154 continue; 155 - } 155 + } 156 156 if (must_refcnt){ 157 157 must_refcnt = 0; 158 158 if (qeth_eddp_buf_ref_context(buf, ctx)){ ··· 202 202 return flush_cnt; 203 203 } 204 204 205 - static inline int 206 - qeth_get_skb_data_len(struct sk_buff *skb) 207 - { 208 - int len = skb->len; 209 - int i; 210 - 211 - for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) 212 - len -= skb_shinfo(skb)->frags[i].size; 213 - return len; 214 - } 215 - 216 205 static inline void 217 206 qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, 218 - struct qeth_eddp_data *eddp) 207 + struct qeth_eddp_data *eddp, int data_len) 219 208 { 220 209 u8 *page; 221 210 int page_remainder; 222 211 int page_offset; 223 - int hdr_len; 212 + int pkt_len; 224 213 struct qeth_eddp_element *element; 225 214 226 215 QETH_DBF_TEXT(trace, 5, "eddpcrsh"); 227 216 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; 228 217 page_offset = ctx->offset % PAGE_SIZE; 229 218 element = &ctx->elements[ctx->num_elements]; 230 - hdr_len = eddp->nhl + eddp->thl; 219 + pkt_len = eddp->nhl + eddp->thl + data_len; 231 220 /* FIXME: layer2 and VLAN !!! */ 232 221 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) 233 - hdr_len += ETH_HLEN; 222 + pkt_len += ETH_HLEN; 234 223 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) 235 - hdr_len += VLAN_HLEN; 236 - /* does complete header fit in current page ? */ 224 + pkt_len += VLAN_HLEN; 225 + /* does complete packet fit in current page ? */ 237 226 page_remainder = PAGE_SIZE - page_offset; 238 - if (page_remainder < (sizeof(struct qeth_hdr) + hdr_len)){ 227 + if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){ 239 228 /* no -> go to start of next page */ 240 229 ctx->offset += page_remainder; 241 230 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; ··· 270 281 int left_in_frag; 271 282 int copy_len; 272 283 u8 *src; 273 - 284 + 274 285 QETH_DBF_TEXT(trace, 5, "eddpcdtc"); 275 286 if (skb_shinfo(eddp->skb)->nr_frags == 0) { 276 287 memcpy(dst, eddp->skb->data + eddp->skb_offset, len); ··· 281 292 while (len > 0) { 282 293 if (eddp->frag < 0) { 283 294 /* we're in skb->data */ 284 - left_in_frag = qeth_get_skb_data_len(eddp->skb) 295 + left_in_frag = (eddp->skb->len - eddp->skb->data_len) 285 296 - eddp->skb_offset; 286 297 src = eddp->skb->data + eddp->skb_offset; 287 298 } else { ··· 413 424 struct tcphdr *tcph; 414 425 int data_len; 415 426 u32 hcsum; 416 - 427 + 417 428 QETH_DBF_TEXT(trace, 5, "eddpftcp"); 418 429 eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; 419 430 tcph = eddp->skb->h.th; ··· 453 464 else 454 465 hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len); 455 466 /* fill the next segment into the context */ 456 - qeth_eddp_create_segment_hdrs(ctx, eddp); 467 + qeth_eddp_create_segment_hdrs(ctx, eddp, data_len); 457 468 qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum); 458 469 if (eddp->skb_offset >= eddp->skb->len) 459 470 break; ··· 463 474 eddp->th.tcp.h.seq += data_len; 464 475 } 465 476 } 466 - 477 + 467 478 static inline int 468 479 qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 469 480 struct sk_buff *skb, struct qeth_hdr *qhdr) 470 481 { 471 482 struct qeth_eddp_data *eddp = NULL; 472 - 483 + 473 484 QETH_DBF_TEXT(trace, 5, "eddpficx"); 474 485 /* create our segmentation headers and copy original headers */ 475 486 if (skb->protocol == ETH_P_IP) ··· 509 520 int hdr_len) 510 521 { 511 522 int skbs_per_page; 512 - 523 + 513 524 QETH_DBF_TEXT(trace, 5, "eddpcanp"); 514 525 /* can we put multiple skbs in one page? */ 515 526 skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); ··· 589 600 struct qeth_hdr *qhdr) 590 601 { 591 602 struct qeth_eddp_context *ctx = NULL; 592 - 603 + 593 604 QETH_DBF_TEXT(trace, 5, "creddpct"); 594 605 if (skb->protocol == ETH_P_IP) 595 606 ctx = qeth_eddp_create_context_generic(card, skb,
+213 -103
drivers/s390/net/qeth_main.c
··· 1 1 /* 2 2 * 3 - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.206 $) 3 + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $) 4 4 * 5 5 * Linux on zSeries OSA Express and HiperSockets support 6 6 * ··· 12 12 * Frank Pavlic (pavlic@de.ibm.com) and 13 13 * Thomas Spatzier <tspat@de.ibm.com> 14 14 * 15 - * $Revision: 1.206 $ $Date: 2005/03/24 09:04:18 $ 15 + * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ 16 16 * 17 17 * This program is free software; you can redistribute it and/or modify 18 18 * it under the terms of the GNU General Public License as published by ··· 80 80 #include "qeth_eddp.h" 81 81 #include "qeth_tso.h" 82 82 83 - #define VERSION_QETH_C "$Revision: 1.206 $" 83 + #define VERSION_QETH_C "$Revision: 1.214 $" 84 84 static const char *version = "qeth S/390 OSA-Express driver"; 85 85 86 86 /** ··· 157 157 158 158 static int 159 159 qeth_set_online(struct ccwgroup_device *); 160 + 161 + static int 162 + __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode); 160 163 161 164 static struct qeth_ipaddr * 162 165 qeth_get_addr_buffer(enum qeth_prot_versions); ··· 513 510 wake_up(&card->wait_q); 514 511 } 515 512 516 - static int qeth_stop_card(struct qeth_card *); 513 + static int qeth_stop_card(struct qeth_card *, int); 517 514 518 515 static int 519 - qeth_set_offline(struct ccwgroup_device *cgdev) 516 + __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) 520 517 { 521 518 struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; 522 519 int rc = 0; ··· 526 523 QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); 527 524 528 525 recover_flag = card->state; 529 - if (qeth_stop_card(card) == -ERESTARTSYS){ 526 + if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ 530 527 PRINT_WARN("Stopping card %s interrupted by user!\n", 531 528 CARD_BUS_ID(card)); 532 529 return -ERESTARTSYS; ··· 540 537 card->state = CARD_STATE_RECOVER; 541 538 qeth_notify_processes(); 542 539 return 0; 540 + } 541 + 542 + static int 543 + qeth_set_offline(struct ccwgroup_device *cgdev) 544 + { 545 + return __qeth_set_offline(cgdev, 0); 543 546 } 544 547 545 548 static int ··· 962 953 PRINT_WARN("Recovery of device %s started ...\n", 963 954 CARD_BUS_ID(card)); 964 955 card->use_hard_stop = 1; 965 - qeth_set_offline(card->gdev); 966 - rc = qeth_set_online(card->gdev); 956 + __qeth_set_offline(card->gdev,1); 957 + rc = __qeth_set_online(card->gdev,1); 967 958 if (!rc) 968 959 PRINT_INFO("Device %s successfully recovered!\n", 969 960 CARD_BUS_ID(card)); ··· 2161 2152 if (!skb_len) 2162 2153 return NULL; 2163 2154 if (card->options.fake_ll){ 2164 - if (!(skb = qeth_get_skb(skb_len + QETH_FAKE_LL_LEN))) 2165 - goto no_mem; 2166 - skb_pull(skb, QETH_FAKE_LL_LEN); 2155 + if(card->dev->type == ARPHRD_IEEE802_TR){ 2156 + if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR))) 2157 + goto no_mem; 2158 + skb_reserve(skb,QETH_FAKE_LL_LEN_TR); 2159 + } else { 2160 + if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH))) 2161 + goto no_mem; 2162 + skb_reserve(skb,QETH_FAKE_LL_LEN_ETH); 2163 + } 2167 2164 } else if (!(skb = qeth_get_skb(skb_len))) 2168 2165 goto no_mem; 2169 2166 data_ptr = element->addr + offset; ··· 2244 2229 } 2245 2230 2246 2231 static inline void 2247 - qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, 2232 + qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb, 2233 + struct qeth_hdr *hdr) 2234 + { 2235 + struct trh_hdr *fake_hdr; 2236 + struct trllc *fake_llc; 2237 + struct iphdr *ip_hdr; 2238 + 2239 + QETH_DBF_TEXT(trace,5,"skbfktr"); 2240 + skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_TR; 2241 + /* this is a fake ethernet header */ 2242 + fake_hdr = (struct trh_hdr *) skb->mac.raw; 2243 + 2244 + /* the destination MAC address */ 2245 + switch (skb->pkt_type){ 2246 + case PACKET_MULTICAST: 2247 + switch (skb->protocol){ 2248 + #ifdef CONFIG_QETH_IPV6 2249 + case __constant_htons(ETH_P_IPV6): 2250 + ndisc_mc_map((struct in6_addr *) 2251 + skb->data + QETH_FAKE_LL_V6_ADDR_POS, 2252 + fake_hdr->daddr, card->dev, 0); 2253 + break; 2254 + #endif /* CONFIG_QETH_IPV6 */ 2255 + case __constant_htons(ETH_P_IP): 2256 + ip_hdr = (struct iphdr *)skb->data; 2257 + ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr); 2258 + break; 2259 + default: 2260 + memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN); 2261 + } 2262 + break; 2263 + case PACKET_BROADCAST: 2264 + memset(fake_hdr->daddr, 0xff, TR_ALEN); 2265 + break; 2266 + default: 2267 + memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN); 2268 + } 2269 + /* the source MAC address */ 2270 + if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR) 2271 + memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN); 2272 + else 2273 + memset(fake_hdr->saddr, 0, TR_ALEN); 2274 + fake_hdr->rcf=0; 2275 + fake_llc = (struct trllc*)&(fake_hdr->rcf); 2276 + fake_llc->dsap = EXTENDED_SAP; 2277 + fake_llc->ssap = EXTENDED_SAP; 2278 + fake_llc->llc = UI_CMD; 2279 + fake_llc->protid[0] = 0; 2280 + fake_llc->protid[1] = 0; 2281 + fake_llc->protid[2] = 0; 2282 + fake_llc->ethertype = ETH_P_IP; 2283 + } 2284 + 2285 + static inline void 2286 + qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb, 2248 2287 struct qeth_hdr *hdr) 2249 2288 { 2250 2289 struct ethhdr *fake_hdr; 2251 2290 struct iphdr *ip_hdr; 2252 2291 2253 - QETH_DBF_TEXT(trace,5,"skbfake"); 2254 - skb->mac.raw = skb->data - QETH_FAKE_LL_LEN; 2292 + QETH_DBF_TEXT(trace,5,"skbfketh"); 2293 + skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_ETH; 2255 2294 /* this is a fake ethernet header */ 2256 2295 fake_hdr = (struct ethhdr *) skb->mac.raw; 2257 2296 ··· 2322 2253 #endif /* CONFIG_QETH_IPV6 */ 2323 2254 case __constant_htons(ETH_P_IP): 2324 2255 ip_hdr = (struct iphdr *)skb->data; 2325 - if (card->dev->type == ARPHRD_IEEE802_TR) 2326 - ip_tr_mc_map(ip_hdr->daddr, fake_hdr->h_dest); 2327 - else 2328 - ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest); 2256 + ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest); 2329 2257 break; 2330 2258 default: 2331 2259 memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN); ··· 2341 2275 memset(fake_hdr->h_source, 0, ETH_ALEN); 2342 2276 /* the protocol */ 2343 2277 fake_hdr->h_proto = skb->protocol; 2278 + } 2279 + 2280 + static inline void 2281 + qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, 2282 + struct qeth_hdr *hdr) 2283 + { 2284 + if (card->dev->type == ARPHRD_IEEE802_TR) 2285 + qeth_rebuild_skb_fake_ll_tr(card, skb, hdr); 2286 + else 2287 + qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); 2344 2288 } 2345 2289 2346 2290 static inline void ··· 3516 3440 unsigned short type, void *daddr, void *saddr, 3517 3441 unsigned len) 3518 3442 { 3519 - struct ethhdr *hdr; 3443 + if(dev->type == ARPHRD_IEEE802_TR){ 3444 + struct trh_hdr *hdr; 3445 + hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR); 3446 + memcpy(hdr->saddr, dev->dev_addr, TR_ALEN); 3447 + memcpy(hdr->daddr, "FAKELL", TR_ALEN); 3448 + return QETH_FAKE_LL_LEN_TR; 3520 3449 3521 - hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN); 3522 - memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN); 3523 - memcpy(hdr->h_dest, "FAKELL", ETH_ALEN); 3524 - if (type != ETH_P_802_3) 3525 - hdr->h_proto = htons(type); 3526 - else 3527 - hdr->h_proto = htons(len); 3528 - return QETH_FAKE_LL_LEN; 3450 + } else { 3451 + struct ethhdr *hdr; 3452 + hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH); 3453 + memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN); 3454 + memcpy(hdr->h_dest, "FAKELL", ETH_ALEN); 3455 + if (type != ETH_P_802_3) 3456 + hdr->h_proto = htons(type); 3457 + else 3458 + hdr->h_proto = htons(len); 3459 + return QETH_FAKE_LL_LEN_ETH; 3460 + 3461 + } 3529 3462 } 3530 3463 3531 3464 static inline int ··· 3795 3710 qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, 3796 3711 struct qeth_hdr **hdr, int ipv) 3797 3712 { 3798 - int rc = 0; 3799 3713 #ifdef CONFIG_QETH_VLAN 3800 3714 u16 *tag; 3801 3715 #endif 3802 3716 3803 3717 QETH_DBF_TEXT(trace, 6, "prepskb"); 3804 3718 3805 - rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); 3806 - if (rc) 3807 - return rc; 3808 3719 #ifdef CONFIG_QETH_VLAN 3809 3720 if (card->vlangrp && vlan_tx_tag_present(*skb) && 3810 3721 ((ipv == 6) || card->options.layer2) ) { ··· 3963 3882 memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16); 3964 3883 } 3965 3884 } else { /* passthrough */ 3966 - if (!memcmp(skb->data + sizeof(struct qeth_hdr), 3885 + if((skb->dev->type == ARPHRD_IEEE802_TR) && 3886 + !memcmp(skb->data + sizeof(struct qeth_hdr) + 3887 + sizeof(__u16), skb->dev->broadcast, 6)) { 3888 + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | 3889 + QETH_HDR_PASSTHRU; 3890 + } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), 3967 3891 skb->dev->broadcast, 6)) { /* broadcast? */ 3968 - hdr->hdr.l3.flags = QETH_CAST_BROADCAST | QETH_HDR_PASSTHRU; 3892 + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | 3893 + QETH_HDR_PASSTHRU; 3969 3894 } else { 3970 3895 hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ? 3971 3896 QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU : ··· 3981 3894 } 3982 3895 3983 3896 static inline void 3984 - __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, 3985 - int *next_element_to_fill) 3986 - { 3987 - int length = skb->len; 3988 - struct skb_frag_struct *frag; 3989 - int fragno; 3990 - unsigned long addr; 3991 - int element; 3992 - int first_lap = 1; 3993 - 3994 - fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */ 3995 - element = *next_element_to_fill + fragno; 3996 - while (length > 0) { 3997 - if (fragno > 0) { 3998 - frag = &skb_shinfo(skb)->frags[fragno - 1]; 3999 - addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + 4000 - frag->page_offset; 4001 - buffer->element[element].addr = (char *)addr; 4002 - buffer->element[element].length = frag->size; 4003 - length -= frag->size; 4004 - if (first_lap) 4005 - buffer->element[element].flags = 4006 - SBAL_FLAGS_LAST_FRAG; 4007 - else 4008 - buffer->element[element].flags = 4009 - SBAL_FLAGS_MIDDLE_FRAG; 4010 - } else { 4011 - buffer->element[element].addr = skb->data; 4012 - buffer->element[element].length = length; 4013 - length = 0; 4014 - buffer->element[element].flags = 4015 - SBAL_FLAGS_FIRST_FRAG; 4016 - } 4017 - element--; 4018 - fragno--; 4019 - first_lap = 0; 4020 - } 4021 - *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1; 4022 - } 4023 - 4024 - static inline void 4025 3897 __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, 4026 - int *next_element_to_fill) 3898 + int is_tso, int *next_element_to_fill) 4027 3899 { 4028 3900 int length = skb->len; 4029 3901 int length_here; 4030 3902 int element; 4031 3903 char *data; 4032 - int first_lap = 1; 3904 + int first_lap ; 4033 3905 4034 3906 element = *next_element_to_fill; 4035 3907 data = skb->data; 3908 + first_lap = (is_tso == 0 ? 1 : 0); 3909 + 4036 3910 while (length > 0) { 4037 3911 /* length_here is the remaining amount of data in this page */ 4038 3912 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); 4039 3913 if (length < length_here) 4040 3914 length_here = length; 3915 + 4041 3916 buffer->element[element].addr = data; 4042 3917 buffer->element[element].length = length_here; 4043 3918 length -= length_here; 4044 - if (!length){ 3919 + if (!length) { 4045 3920 if (first_lap) 4046 3921 buffer->element[element].flags = 0; 4047 3922 else ··· 4030 3981 struct sk_buff *skb) 4031 3982 { 4032 3983 struct qdio_buffer *buffer; 4033 - int flush_cnt = 0; 3984 + struct qeth_hdr_tso *hdr; 3985 + int flush_cnt = 0, hdr_len, large_send = 0; 4034 3986 4035 3987 QETH_DBF_TEXT(trace, 6, "qdfillbf"); 3988 + 4036 3989 buffer = buf->buffer; 4037 3990 atomic_inc(&skb->users); 4038 3991 skb_queue_tail(&buf->skb_list, skb); 3992 + 3993 + hdr = (struct qeth_hdr_tso *) skb->data; 3994 + /*check first on TSO ....*/ 3995 + if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) { 3996 + int element = buf->next_element_to_fill; 3997 + 3998 + hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len; 3999 + /*fill first buffer entry only with header information */ 4000 + buffer->element[element].addr = skb->data; 4001 + buffer->element[element].length = hdr_len; 4002 + buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG; 4003 + buf->next_element_to_fill++; 4004 + skb->data += hdr_len; 4005 + skb->len -= hdr_len; 4006 + large_send = 1; 4007 + } 4039 4008 if (skb_shinfo(skb)->nr_frags == 0) 4040 - __qeth_fill_buffer(skb, buffer, 4009 + __qeth_fill_buffer(skb, buffer, large_send, 4041 4010 (int *)&buf->next_element_to_fill); 4042 4011 else 4043 - __qeth_fill_buffer_frag(skb, buffer, 4012 + __qeth_fill_buffer_frag(skb, buffer, large_send, 4044 4013 (int *)&buf->next_element_to_fill); 4045 4014 4046 4015 if (!queue->do_pack) { ··· 4251 4184 } 4252 4185 4253 4186 static inline int 4187 + qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) 4188 + { 4189 + int elements_needed = 0; 4190 + 4191 + if (skb_shinfo(skb)->nr_frags > 0) { 4192 + elements_needed = (skb_shinfo(skb)->nr_frags + 1); 4193 + } 4194 + if (elements_needed == 0 ) 4195 + elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) 4196 + + skb->len) >> PAGE_SHIFT); 4197 + if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ 4198 + PRINT_ERR("qeth_do_send_packet: invalid size of " 4199 + "IP packet. Discarded."); 4200 + return 0; 4201 + } 4202 + return elements_needed; 4203 + } 4204 + 4205 + static inline int 4254 4206 qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) 4255 4207 { 4256 4208 int ipv = 0; ··· 4291 4205 dev_kfree_skb_irq(skb); 4292 4206 return 0; 4293 4207 } 4294 - skb_pull(skb, QETH_FAKE_LL_LEN); 4208 + if(card->dev->type == ARPHRD_IEEE802_TR){ 4209 + skb_pull(skb, QETH_FAKE_LL_LEN_TR); 4210 + } else { 4211 + skb_pull(skb, QETH_FAKE_LL_LEN_ETH); 4212 + } 4295 4213 } 4296 4214 } 4297 4215 cast_type = qeth_get_cast_type(card, skb); ··· 4311 4221 if (skb_shinfo(skb)->tso_size) 4312 4222 large_send = card->options.large_send; 4313 4223 4314 - if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))){ 4315 - QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); 4316 - return rc; 4317 - } 4318 4224 /*are we able to do TSO ? If so ,prepare and send it from here */ 4319 4225 if ((large_send == QETH_LARGE_SEND_TSO) && 4320 4226 (cast_type == RTN_UNSPEC)) { 4321 - rc = qeth_tso_send_packet(card, skb, queue, 4322 - ipv, cast_type); 4323 - goto do_statistics; 4227 + rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type); 4228 + if (rc) { 4229 + card->stats.tx_dropped++; 4230 + card->stats.tx_errors++; 4231 + dev_kfree_skb_any(skb); 4232 + return NETDEV_TX_OK; 4233 + } 4234 + elements_needed++; 4235 + } else { 4236 + if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) { 4237 + QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); 4238 + return rc; 4239 + } 4240 + qeth_fill_header(card, hdr, skb, ipv, cast_type); 4324 4241 } 4325 4242 4326 - qeth_fill_header(card, hdr, skb, ipv, cast_type); 4327 4243 if (large_send == QETH_LARGE_SEND_EDDP) { 4328 4244 ctx = qeth_eddp_create_context(card, skb, hdr); 4329 4245 if (ctx == NULL) { ··· 4337 4241 return -EINVAL; 4338 4242 } 4339 4243 } else { 4340 - elements_needed = qeth_get_elements_no(card,(void*) hdr, skb); 4244 + elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); 4341 4245 if (!elements_needed) 4342 4246 return -EINVAL; 4343 4247 } ··· 4348 4252 else 4349 4253 rc = qeth_do_send_packet_fast(card, queue, skb, hdr, 4350 4254 elements_needed, ctx); 4351 - do_statistics: 4352 4255 if (!rc){ 4353 4256 card->stats.tx_packets++; 4354 4257 card->stats.tx_bytes += skb->len; 4355 4258 #ifdef CONFIG_QETH_PERF_STATS 4356 - if (skb_shinfo(skb)->tso_size) { 4259 + if (skb_shinfo(skb)->tso_size && 4260 + !(large_send == QETH_LARGE_SEND_NO)) { 4357 4261 card->perf_stats.large_send_bytes += skb->len; 4358 4262 card->perf_stats.large_send_cnt++; 4359 4263 } ··· 7250 7154 } 7251 7155 7252 7156 static int 7253 - qeth_stop_card(struct qeth_card *card) 7157 + qeth_stop_card(struct qeth_card *card, int recovery_mode) 7254 7158 { 7255 7159 int rc = 0; 7256 7160 ··· 7263 7167 if (card->read.state == CH_STATE_UP && 7264 7168 card->write.state == CH_STATE_UP && 7265 7169 (card->state == CARD_STATE_UP)) { 7266 - rtnl_lock(); 7267 - dev_close(card->dev); 7268 - rtnl_unlock(); 7170 + if(recovery_mode) { 7171 + qeth_stop(card->dev); 7172 + } else { 7173 + rtnl_lock(); 7174 + dev_close(card->dev); 7175 + rtnl_unlock(); 7176 + } 7269 7177 if (!card->use_hard_stop) { 7270 7178 __u8 *mac = &card->dev->dev_addr[0]; 7271 7179 rc = qeth_layer2_send_delmac(card, mac); ··· 7441 7341 } 7442 7342 7443 7343 static void 7444 - qeth_start_again(struct qeth_card *card) 7344 + qeth_start_again(struct qeth_card *card, int recovery_mode) 7445 7345 { 7446 7346 QETH_DBF_TEXT(setup ,2, "startag"); 7447 7347 7448 - rtnl_lock(); 7449 - dev_open(card->dev); 7450 - rtnl_unlock(); 7348 + if(recovery_mode) { 7349 + qeth_open(card->dev); 7350 + } else { 7351 + rtnl_lock(); 7352 + dev_open(card->dev); 7353 + rtnl_unlock(); 7354 + } 7451 7355 /* this also sets saved unicast addresses */ 7452 7356 qeth_set_multicast_list(card->dev); 7453 7357 } ··· 7508 7404 7509 7405 7510 7406 static int 7511 - qeth_set_online(struct ccwgroup_device *gdev) 7407 + __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode) 7512 7408 { 7513 7409 struct qeth_card *card = gdev->dev.driver_data; 7514 7410 int rc = 0; ··· 7568 7464 * we can also use this state for recovery purposes*/ 7569 7465 qeth_set_allowed_threads(card, 0xffffffff, 0); 7570 7466 if (recover_flag == CARD_STATE_RECOVER) 7571 - qeth_start_again(card); 7467 + qeth_start_again(card, recovery_mode); 7572 7468 qeth_notify_processes(); 7573 7469 return 0; 7574 7470 out_remove: 7575 7471 card->use_hard_stop = 1; 7576 - qeth_stop_card(card); 7472 + qeth_stop_card(card, 0); 7577 7473 ccw_device_set_offline(CARD_DDEV(card)); 7578 7474 ccw_device_set_offline(CARD_WDEV(card)); 7579 7475 ccw_device_set_offline(CARD_RDEV(card)); ··· 7582 7478 else 7583 7479 card->state = CARD_STATE_DOWN; 7584 7480 return -ENODEV; 7481 + } 7482 + 7483 + static int 7484 + qeth_set_online(struct ccwgroup_device *gdev) 7485 + { 7486 + return __qeth_set_online(gdev, 0); 7585 7487 } 7586 7488 7587 7489 static struct ccw_device_id qeth_ids[] = {
-285
drivers/s390/net/qeth_tso.c
··· 1 - /* 2 - * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.6 $) 3 - * 4 - * Header file for qeth TCP Segmentation Offload support. 5 - * 6 - * Copyright 2004 IBM Corporation 7 - * 8 - * Author(s): Frank Pavlic <pavlic@de.ibm.com> 9 - * 10 - * $Revision: 1.6 $ $Date: 2005/03/24 09:04:18 $ 11 - * 12 - */ 13 - 14 - #include <linux/skbuff.h> 15 - #include <linux/tcp.h> 16 - #include <linux/ip.h> 17 - #include <linux/ipv6.h> 18 - #include <net/ip6_checksum.h> 19 - #include "qeth.h" 20 - #include "qeth_mpc.h" 21 - #include "qeth_tso.h" 22 - 23 - /** 24 - * skb already partially prepared 25 - * classic qdio header in skb->data 26 - * */ 27 - static inline struct qeth_hdr_tso * 28 - qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) 29 - { 30 - int rc = 0; 31 - 32 - QETH_DBF_TEXT(trace, 5, "tsoprsk"); 33 - rc = qeth_realloc_headroom(card, skb,sizeof(struct qeth_hdr_ext_tso)); 34 - if (rc) 35 - return NULL; 36 - 37 - return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_ext_tso)); 38 - } 39 - 40 - /** 41 - * fill header for a TSO packet 42 - */ 43 - static inline void 44 - qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) 45 - { 46 - struct qeth_hdr_tso *hdr; 47 - struct tcphdr *tcph; 48 - struct iphdr *iph; 49 - 50 - QETH_DBF_TEXT(trace, 5, "tsofhdr"); 51 - 52 - hdr = (struct qeth_hdr_tso *) skb->data; 53 - iph = skb->nh.iph; 54 - tcph = skb->h.th; 55 - /*fix header to TSO values ...*/ 56 - hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; 57 - /*set values which are fix for the first approach ...*/ 58 - hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); 59 - hdr->ext.imb_hdr_no = 1; 60 - hdr->ext.hdr_type = 1; 61 - hdr->ext.hdr_version = 1; 62 - hdr->ext.hdr_len = 28; 63 - /*insert non-fix values */ 64 - hdr->ext.mss = skb_shinfo(skb)->tso_size; 65 - hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); 66 - hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - 67 - sizeof(struct qeth_hdr_tso)); 68 - } 69 - 70 - /** 71 - * change some header values as requested by hardware 72 - */ 73 - static inline void 74 - qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb) 75 - { 76 - struct iphdr *iph; 77 - struct ipv6hdr *ip6h; 78 - struct tcphdr *tcph; 79 - 80 - iph = skb->nh.iph; 81 - ip6h = skb->nh.ipv6h; 82 - tcph = skb->h.th; 83 - 84 - tcph->check = 0; 85 - if (skb->protocol == ETH_P_IPV6) { 86 - ip6h->payload_len = 0; 87 - tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 88 - 0, IPPROTO_TCP, 0); 89 - return; 90 - } 91 - /*OSA want us to set these values ...*/ 92 - tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 93 - 0, IPPROTO_TCP, 0); 94 - iph->tot_len = 0; 95 - iph->check = 0; 96 - } 97 - 98 - static inline struct qeth_hdr_tso * 99 - qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb, 100 - int ipv, int cast_type) 101 - { 102 - struct qeth_hdr_tso *hdr; 103 - int rc = 0; 104 - 105 - QETH_DBF_TEXT(trace, 5, "tsoprep"); 106 - 107 - /*get headroom for tso qdio header */ 108 - hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb); 109 - if (hdr == NULL) { 110 - QETH_DBF_TEXT_(trace, 4, "2err%d", rc); 111 - return NULL; 112 - } 113 - memset(hdr, 0, sizeof(struct qeth_hdr_tso)); 114 - /*fill first 32 bytes of qdio header as used 115 - *FIXME: TSO has two struct members 116 - * with different names but same size 117 - * */ 118 - qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type); 119 - qeth_tso_fill_header(card, skb); 120 - qeth_tso_set_tcpip_header(card, skb); 121 - return hdr; 122 - } 123 - 124 - static inline int 125 - qeth_tso_get_queue_buffer(struct qeth_qdio_out_q *queue) 126 - { 127 - struct qeth_qdio_out_buffer *buffer; 128 - int flush_cnt = 0; 129 - 130 - QETH_DBF_TEXT(trace, 5, "tsobuf"); 131 - 132 - /* force to non-packing*/ 133 - if (queue->do_pack) 134 - queue->do_pack = 0; 135 - buffer = &queue->bufs[queue->next_buf_to_fill]; 136 - /* get a new buffer if current is already in use*/ 137 - if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) && 138 - (buffer->next_element_to_fill > 0)) { 139 - atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); 140 - queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % 141 - QDIO_MAX_BUFFERS_PER_Q; 142 - flush_cnt++; 143 - } 144 - return flush_cnt; 145 - } 146 - 147 - static inline void 148 - __qeth_tso_fill_buffer_frag(struct qeth_qdio_out_buffer *buf, 149 - struct sk_buff *skb) 150 - { 151 - struct skb_frag_struct *frag; 152 - struct qdio_buffer *buffer; 153 - int fragno, cnt, element; 154 - unsigned long addr; 155 - 156 - QETH_DBF_TEXT(trace, 6, "tsfilfrg"); 157 - 158 - /*initialize variables ...*/ 159 - fragno = skb_shinfo(skb)->nr_frags; 160 - buffer = buf->buffer; 161 - element = buf->next_element_to_fill; 162 - /*fill buffer elements .....*/ 163 - for (cnt = 0; cnt < fragno; cnt++) { 164 - frag = &skb_shinfo(skb)->frags[cnt]; 165 - addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + 166 - frag->page_offset; 167 - buffer->element[element].addr = (char *)addr; 168 - buffer->element[element].length = frag->size; 169 - if (cnt < (fragno - 1)) 170 - buffer->element[element].flags = 171 - SBAL_FLAGS_MIDDLE_FRAG; 172 - else 173 - buffer->element[element].flags = 174 - SBAL_FLAGS_LAST_FRAG; 175 - element++; 176 - } 177 - buf->next_element_to_fill = element; 178 - } 179 - 180 - static inline int 181 - qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf, 182 - struct sk_buff *skb) 183 - { 184 - int length, length_here, element; 185 - int hdr_len; 186 - struct qdio_buffer *buffer; 187 - struct qeth_hdr_tso *hdr; 188 - char *data; 189 - 190 - QETH_DBF_TEXT(trace, 3, "tsfilbuf"); 191 - 192 - /*increment user count and queue skb ...*/ 193 - atomic_inc(&skb->users); 194 - skb_queue_tail(&buf->skb_list, skb); 195 - 196 - /*initialize all variables...*/ 197 - buffer = buf->buffer; 198 - hdr = (struct qeth_hdr_tso *)skb->data; 199 - hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len; 200 - data = skb->data + hdr_len; 201 - length = skb->len - hdr_len; 202 - element = buf->next_element_to_fill; 203 - /*fill first buffer entry only with header information */ 204 - buffer->element[element].addr = skb->data; 205 - buffer->element[element].length = hdr_len; 206 - buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG; 207 - buf->next_element_to_fill++; 208 - 209 - if (skb_shinfo(skb)->nr_frags > 0) { 210 - __qeth_tso_fill_buffer_frag(buf, skb); 211 - goto out; 212 - } 213 - 214 - /*start filling buffer entries ...*/ 215 - element++; 216 - while (length > 0) { 217 - /* length_here is the remaining amount of data in this page */ 218 - length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); 219 - if (length < length_here) 220 - length_here = length; 221 - buffer->element[element].addr = data; 222 - buffer->element[element].length = length_here; 223 - length -= length_here; 224 - if (!length) 225 - buffer->element[element].flags = 226 - SBAL_FLAGS_LAST_FRAG; 227 - else 228 - buffer->element[element].flags = 229 - SBAL_FLAGS_MIDDLE_FRAG; 230 - data += length_here; 231 - element++; 232 - } 233 - /*set the buffer to primed ...*/ 234 - buf->next_element_to_fill = element; 235 - out: 236 - atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); 237 - return 1; 238 - } 239 - 240 - int 241 - qeth_tso_send_packet(struct qeth_card *card, struct sk_buff *skb, 242 - struct qeth_qdio_out_q *queue, int ipv, int cast_type) 243 - { 244 - int flush_cnt = 0; 245 - struct qeth_hdr_tso *hdr; 246 - struct qeth_qdio_out_buffer *buffer; 247 - int start_index; 248 - 249 - QETH_DBF_TEXT(trace, 3, "tsosend"); 250 - 251 - if (!(hdr = qeth_tso_prepare_packet(card, skb, ipv, cast_type))) 252 - return -ENOMEM; 253 - /*check if skb fits in one SBAL ...*/ 254 - if (!(qeth_get_elements_no(card, (void*)hdr, skb))) 255 - return -EINVAL; 256 - /*lock queue, force switching to non-packing and send it ...*/ 257 - while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED, 258 - QETH_OUT_Q_LOCKED, 259 - &queue->state)); 260 - start_index = queue->next_buf_to_fill; 261 - buffer = &queue->bufs[queue->next_buf_to_fill]; 262 - /*check if card is too busy ...*/ 263 - if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ 264 - card->stats.tx_dropped++; 265 - goto out; 266 - } 267 - /*let's force to non-packing and get a new SBAL*/ 268 - flush_cnt += qeth_tso_get_queue_buffer(queue); 269 - buffer = &queue->bufs[queue->next_buf_to_fill]; 270 - if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { 271 - card->stats.tx_dropped++; 272 - goto out; 273 - } 274 - flush_cnt += qeth_tso_fill_buffer(buffer, skb); 275 - queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % 276 - QDIO_MAX_BUFFERS_PER_Q; 277 - out: 278 - atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); 279 - if (flush_cnt) 280 - qeth_flush_buffers(queue, 0, start_index, flush_cnt); 281 - /*do some statistics */ 282 - card->stats.tx_packets++; 283 - card->stats.tx_bytes += skb->len; 284 - return 0; 285 - }
+130 -34
drivers/s390/net/qeth_tso.h
··· 1 1 /* 2 - * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.4 $) 2 + * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $) 3 3 * 4 4 * Header file for qeth TCP Segmentation Offload support. 5 5 * ··· 7 7 * 8 8 * Author(s): Frank Pavlic <pavlic@de.ibm.com> 9 9 * 10 - * $Revision: 1.4 $ $Date: 2005/03/24 09:04:18 $ 10 + * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ 11 11 * 12 12 */ 13 13 #ifndef __QETH_TSO_H__ 14 14 #define __QETH_TSO_H__ 15 15 16 + #include <linux/skbuff.h> 17 + #include <linux/tcp.h> 18 + #include <linux/ip.h> 19 + #include <linux/ipv6.h> 20 + #include <net/ip6_checksum.h> 21 + #include "qeth.h" 22 + #include "qeth_mpc.h" 16 23 17 - extern int 18 - qeth_tso_send_packet(struct qeth_card *, struct sk_buff *, 19 - struct qeth_qdio_out_q *, int , int); 20 24 21 - struct qeth_hdr_ext_tso { 22 - __u16 hdr_tot_len; 23 - __u8 imb_hdr_no; 24 - __u8 reserved; 25 - __u8 hdr_type; 26 - __u8 hdr_version; 27 - __u16 hdr_len; 28 - __u32 payload_len; 29 - __u16 mss; 30 - __u16 dg_hdr_len; 31 - __u8 padding[16]; 32 - } __attribute__ ((packed)); 25 + static inline struct qeth_hdr_tso * 26 + qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) 27 + { 28 + QETH_DBF_TEXT(trace, 5, "tsoprsk"); 29 + return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso)); 30 + } 33 31 34 - struct qeth_hdr_tso { 35 - struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ 36 - struct qeth_hdr_ext_tso ext; 37 - } __attribute__ ((packed)); 32 + /** 33 + * fill header for a TSO packet 34 + */ 35 + static inline void 36 + qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) 37 + { 38 + struct qeth_hdr_tso *hdr; 39 + struct tcphdr *tcph; 40 + struct iphdr *iph; 38 41 39 - /*some helper functions*/ 42 + QETH_DBF_TEXT(trace, 5, "tsofhdr"); 43 + 44 + hdr = (struct qeth_hdr_tso *) skb->data; 45 + iph = skb->nh.iph; 46 + tcph = skb->h.th; 47 + /*fix header to TSO values ...*/ 48 + hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; 49 + /*set values which are fix for the first approach ...*/ 50 + hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); 51 + hdr->ext.imb_hdr_no = 1; 52 + hdr->ext.hdr_type = 1; 53 + hdr->ext.hdr_version = 1; 54 + hdr->ext.hdr_len = 28; 55 + /*insert non-fix values */ 56 + hdr->ext.mss = skb_shinfo(skb)->tso_size; 57 + hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); 58 + hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - 59 + sizeof(struct qeth_hdr_tso)); 60 + } 61 + 62 + /** 63 + * change some header values as requested by hardware 64 + */ 65 + static inline void 66 + qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb) 67 + { 68 + struct iphdr *iph; 69 + struct ipv6hdr *ip6h; 70 + struct tcphdr *tcph; 71 + 72 + iph = skb->nh.iph; 73 + ip6h = skb->nh.ipv6h; 74 + tcph = skb->h.th; 75 + 76 + tcph->check = 0; 77 + if (skb->protocol == ETH_P_IPV6) { 78 + ip6h->payload_len = 0; 79 + tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 80 + 0, IPPROTO_TCP, 0); 81 + return; 82 + } 83 + /*OSA want us to set these values ...*/ 84 + tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 85 + 0, IPPROTO_TCP, 0); 86 + iph->tot_len = 0; 87 + iph->check = 0; 88 + } 40 89 41 90 static inline int 42 - qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) 91 + qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb, 92 + int ipv, int cast_type) 43 93 { 44 - int elements_needed = 0; 94 + struct qeth_hdr_tso *hdr; 45 95 46 - if (skb_shinfo(skb)->nr_frags > 0) 47 - elements_needed = (skb_shinfo(skb)->nr_frags + 1); 48 - if (elements_needed == 0 ) 49 - elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) 50 - + skb->len) >> PAGE_SHIFT); 51 - if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ 52 - PRINT_ERR("qeth_do_send_packet: invalid size of " 53 - "IP packet. Discarded."); 54 - return 0; 96 + QETH_DBF_TEXT(trace, 5, "tsoprep"); 97 + 98 + hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb); 99 + if (hdr == NULL) { 100 + QETH_DBF_TEXT(trace, 4, "tsoperr"); 101 + return -ENOMEM; 55 102 } 56 - return elements_needed; 103 + memset(hdr, 0, sizeof(struct qeth_hdr_tso)); 104 + /*fill first 32 bytes of qdio header as used 105 + *FIXME: TSO has two struct members 106 + * with different names but same size 107 + * */ 108 + qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type); 109 + qeth_tso_fill_header(card, skb); 110 + qeth_tso_set_tcpip_header(card, skb); 111 + return 0; 112 + } 113 + 114 + static inline void 115 + __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, 116 + int is_tso, int *next_element_to_fill) 117 + { 118 + struct skb_frag_struct *frag; 119 + int fragno; 120 + unsigned long addr; 121 + int element, cnt, dlen; 122 + 123 + fragno = skb_shinfo(skb)->nr_frags; 124 + element = *next_element_to_fill; 125 + dlen = 0; 126 + 127 + if (is_tso) 128 + buffer->element[element].flags = 129 + SBAL_FLAGS_MIDDLE_FRAG; 130 + else 131 + buffer->element[element].flags = 132 + SBAL_FLAGS_FIRST_FRAG; 133 + if ( (dlen = (skb->len - skb->data_len)) ) { 134 + buffer->element[element].addr = skb->data; 135 + buffer->element[element].length = dlen; 136 + element++; 137 + } 138 + for (cnt = 0; cnt < fragno; cnt++) { 139 + frag = &skb_shinfo(skb)->frags[cnt]; 140 + addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + 141 + frag->page_offset; 142 + buffer->element[element].addr = (char *)addr; 143 + buffer->element[element].length = frag->size; 144 + if (cnt < (fragno - 1)) 145 + buffer->element[element].flags = 146 + SBAL_FLAGS_MIDDLE_FRAG; 147 + else 148 + buffer->element[element].flags = 149 + SBAL_FLAGS_LAST_FRAG; 150 + element++; 151 + } 152 + *next_element_to_fill = element; 57 153 } 58 154 #endif /* __QETH_TSO_H__ */