aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c146
1 files changed, 65 insertions, 81 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index e70642811217..1b31bebc27d6 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -87,6 +87,21 @@ struct avc_response_frame {
87 u8 operand[509]; 87 u8 operand[509];
88}; 88};
89 89
90#define LAST_OPERAND (509 - 1)
91
92static inline void clear_operands(struct avc_command_frame *c, int from, int to)
93{
94 memset(&c->operand[from], 0, to - from + 1);
95}
96
97static void pad_operands(struct avc_command_frame *c, int from)
98{
99 int to = ALIGN(from, 4);
100
101 if (from <= to && to <= LAST_OPERAND)
102 clear_operands(c, from, to);
103}
104
90#define AVC_DEBUG_READ_DESCRIPTOR 0x0001 105#define AVC_DEBUG_READ_DESCRIPTOR 0x0001
91#define AVC_DEBUG_DSIT 0x0002 106#define AVC_DEBUG_DSIT 0x0002
92#define AVC_DEBUG_DSD 0x0004 107#define AVC_DEBUG_DSD 0x0004
@@ -303,8 +318,8 @@ static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
303 * tuning command for setting the relative LNB frequency 318 * tuning command for setting the relative LNB frequency
304 * (not supported by the AVC standard) 319 * (not supported by the AVC standard)
305 */ 320 */
306static void avc_tuner_tuneqpsk(struct firedtv *fdtv, 321static int avc_tuner_tuneqpsk(struct firedtv *fdtv,
307 struct dvb_frontend_parameters *params) 322 struct dvb_frontend_parameters *params)
308{ 323{
309 struct avc_command_frame *c = (void *)fdtv->avc_data; 324 struct avc_command_frame *c = (void *)fdtv->avc_data;
310 325
@@ -356,14 +371,15 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
356 c->operand[13] = 0x1; 371 c->operand[13] = 0x1;
357 c->operand[14] = 0xff; 372 c->operand[14] = 0xff;
358 c->operand[15] = 0xff; 373 c->operand[15] = 0xff;
359 fdtv->avc_data_length = 20; 374
375 return 16;
360 } else { 376 } else {
361 fdtv->avc_data_length = 16; 377 return 13;
362 } 378 }
363} 379}
364 380
365static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, 381static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
366 struct dvb_frontend_parameters *params) 382 struct dvb_frontend_parameters *params)
367{ 383{
368 struct avc_command_frame *c = (void *)fdtv->avc_data; 384 struct avc_command_frame *c = (void *)fdtv->avc_data;
369 385
@@ -427,13 +443,11 @@ static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
427 c->operand[20] = 0x00; 443 c->operand[20] = 0x00;
428 c->operand[21] = 0x00; 444 c->operand[21] = 0x00;
429 445
430 /* Add PIDs to filter */ 446 return 22 + add_pid_filter(fdtv, &c->operand[22]);
431 fdtv->avc_data_length =
432 ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
433} 447}
434 448
435static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, 449static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
436 struct dvb_frontend_parameters *params) 450 struct dvb_frontend_parameters *params)
437{ 451{
438 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm; 452 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
439 struct avc_command_frame *c = (void *)fdtv->avc_data; 453 struct avc_command_frame *c = (void *)fdtv->avc_data;
@@ -531,32 +545,31 @@ static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
531 c->operand[15] = 0x00; /* network_ID[0] */ 545 c->operand[15] = 0x00; /* network_ID[0] */
532 c->operand[16] = 0x00; /* network_ID[1] */ 546 c->operand[16] = 0x00; /* network_ID[1] */
533 547
534 /* Add PIDs to filter */ 548 return 17 + add_pid_filter(fdtv, &c->operand[17]);
535 fdtv->avc_data_length =
536 ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
537} 549}
538 550
539int avc_tuner_dsd(struct firedtv *fdtv, 551int avc_tuner_dsd(struct firedtv *fdtv,
540 struct dvb_frontend_parameters *params) 552 struct dvb_frontend_parameters *params)
541{ 553{
542 struct avc_command_frame *c = (void *)fdtv->avc_data; 554 struct avc_command_frame *c = (void *)fdtv->avc_data;
543 int ret; 555 int pos, ret;
544 556
545 mutex_lock(&fdtv->avc_mutex); 557 mutex_lock(&fdtv->avc_mutex);
546 558
547 memset(c, 0, sizeof(*c));
548
549 c->ctype = AVC_CTYPE_CONTROL; 559 c->ctype = AVC_CTYPE_CONTROL;
550 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 560 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
551 561
552 switch (fdtv->type) { 562 switch (fdtv->type) {
553 case FIREDTV_DVB_S: 563 case FIREDTV_DVB_S:
554 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params); break; 564 case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, params); break;
555 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params); break; 565 case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, params); break;
556 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params); break; 566 case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, params); break;
557 default: 567 default:
558 BUG(); 568 BUG();
559 } 569 }
570 pad_operands(c, pos);
571
572 fdtv->avc_data_length = ALIGN(3 + pos, 4);
560 ret = avc_write(fdtv); 573 ret = avc_write(fdtv);
561#if 0 574#if 0
562 /* 575 /*
@@ -585,8 +598,6 @@ int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
585 598
586 mutex_lock(&fdtv->avc_mutex); 599 mutex_lock(&fdtv->avc_mutex);
587 600
588 memset(c, 0, sizeof(*c));
589
590 c->ctype = AVC_CTYPE_CONTROL; 601 c->ctype = AVC_CTYPE_CONTROL;
591 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 602 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
592 c->opcode = AVC_OPCODE_DSD; 603 c->opcode = AVC_OPCODE_DSD;
@@ -608,6 +619,7 @@ int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
608 c->operand[pos++] = 0x00; /* tableID */ 619 c->operand[pos++] = 0x00; /* tableID */
609 c->operand[pos++] = 0x00; /* filter_length */ 620 c->operand[pos++] = 0x00; /* filter_length */
610 } 621 }
622 pad_operands(c, pos);
611 623
612 fdtv->avc_data_length = ALIGN(3 + pos, 4); 624 fdtv->avc_data_length = ALIGN(3 + pos, 4);
613 ret = avc_write(fdtv); 625 ret = avc_write(fdtv);
@@ -629,8 +641,6 @@ int avc_tuner_get_ts(struct firedtv *fdtv)
629 641
630 mutex_lock(&fdtv->avc_mutex); 642 mutex_lock(&fdtv->avc_mutex);
631 643
632 memset(c, 0, sizeof(*c));
633
634 c->ctype = AVC_CTYPE_CONTROL; 644 c->ctype = AVC_CTYPE_CONTROL;
635 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 645 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
636 c->opcode = AVC_OPCODE_DSIT; 646 c->opcode = AVC_OPCODE_DSIT;
@@ -644,9 +654,12 @@ int avc_tuner_get_ts(struct firedtv *fdtv)
644 c->operand[4] = 0x00; /* antenna number */ 654 c->operand[4] = 0x00; /* antenna number */
645 c->operand[5] = 0x0; /* system_specific_search_flags */ 655 c->operand[5] = 0x0; /* system_specific_search_flags */
646 c->operand[6] = sl; /* system_specific_multiplex selection_length */ 656 c->operand[6] = sl; /* system_specific_multiplex selection_length */
647 c->operand[7] = 0x00; /* valid_flags [0] */ 657 /*
648 c->operand[8] = 0x00; /* valid_flags [1] */ 658 * operand[7]: valid_flags[0]
649 c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ 659 * operand[8]: valid_flags[1]
660 * operand[7 + sl]: nr_of_dsit_sel_specs (always 0)
661 */
662 clear_operands(c, 7, 24);
650 663
651 fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; 664 fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
652 ret = avc_write(fdtv); 665 ret = avc_write(fdtv);
@@ -669,8 +682,6 @@ int avc_identify_subunit(struct firedtv *fdtv)
669 682
670 mutex_lock(&fdtv->avc_mutex); 683 mutex_lock(&fdtv->avc_mutex);
671 684
672 memset(c, 0, sizeof(*c));
673
674 c->ctype = AVC_CTYPE_CONTROL; 685 c->ctype = AVC_CTYPE_CONTROL;
675 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 686 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
676 c->opcode = AVC_OPCODE_READ_DESCRIPTOR; 687 c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
@@ -682,6 +693,7 @@ int avc_identify_subunit(struct firedtv *fdtv)
682 c->operand[4] = 0x08; /* length lowbyte */ 693 c->operand[4] = 0x08; /* length lowbyte */
683 c->operand[5] = 0x00; /* offset highbyte */ 694 c->operand[5] = 0x00; /* offset highbyte */
684 c->operand[6] = 0x0d; /* offset lowbyte */ 695 c->operand[6] = 0x0d; /* offset lowbyte */
696 clear_operands(c, 7, 8); /* padding */
685 697
686 fdtv->avc_data_length = 12; 698 fdtv->avc_data_length = 12;
687 ret = avc_write(fdtv); 699 ret = avc_write(fdtv);
@@ -710,19 +722,18 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
710 722
711 mutex_lock(&fdtv->avc_mutex); 723 mutex_lock(&fdtv->avc_mutex);
712 724
713 memset(c, 0, sizeof(*c));
714
715 c->ctype = AVC_CTYPE_CONTROL; 725 c->ctype = AVC_CTYPE_CONTROL;
716 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 726 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
717 c->opcode = AVC_OPCODE_READ_DESCRIPTOR; 727 c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
718 728
719 c->operand[0] = DESCRIPTOR_TUNER_STATUS; 729 c->operand[0] = DESCRIPTOR_TUNER_STATUS;
720 c->operand[1] = 0xff; /* read_result_status */ 730 c->operand[1] = 0xff; /* read_result_status */
721 c->operand[2] = 0x00; /* reserved */ 731 /*
722 c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ 732 * operand[2]: reserved
723 c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ 733 * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8
724 c->operand[5] = 0x00; 734 * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff
725 c->operand[6] = 0x00; 735 */
736 clear_operands(c, 2, 31);
726 737
727 fdtv->avc_data_length = 12; 738 fdtv->avc_data_length = 12;
728 ret = avc_write(fdtv); 739 ret = avc_write(fdtv);
@@ -788,12 +799,10 @@ int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
788{ 799{
789 struct avc_command_frame *c = (void *)fdtv->avc_data; 800 struct avc_command_frame *c = (void *)fdtv->avc_data;
790 struct avc_response_frame *r = (void *)fdtv->avc_data; 801 struct avc_response_frame *r = (void *)fdtv->avc_data;
791 int i, j, k, ret; 802 int pos, j, k, ret;
792 803
793 mutex_lock(&fdtv->avc_mutex); 804 mutex_lock(&fdtv->avc_mutex);
794 805
795 memset(c, 0, sizeof(*c));
796
797 c->ctype = AVC_CTYPE_CONTROL; 806 c->ctype = AVC_CTYPE_CONTROL;
798 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 807 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
799 c->opcode = AVC_OPCODE_VENDOR; 808 c->opcode = AVC_OPCODE_VENDOR;
@@ -802,23 +811,21 @@ int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
802 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; 811 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
803 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; 812 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
804 c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; 813 c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
805
806 c->operand[4] = voltage; 814 c->operand[4] = voltage;
807 c->operand[5] = nrdiseq; 815 c->operand[5] = nrdiseq;
808 816
809 i = 6; 817 pos = 6;
810
811 for (j = 0; j < nrdiseq; j++) { 818 for (j = 0; j < nrdiseq; j++) {
812 c->operand[i++] = diseqcmd[j].msg_len; 819 c->operand[pos++] = diseqcmd[j].msg_len;
813 820
814 for (k = 0; k < diseqcmd[j].msg_len; k++) 821 for (k = 0; k < diseqcmd[j].msg_len; k++)
815 c->operand[i++] = diseqcmd[j].msg[k]; 822 c->operand[pos++] = diseqcmd[j].msg[k];
816 } 823 }
824 c->operand[pos++] = burst;
825 c->operand[pos++] = conttone;
826 pad_operands(c, pos);
817 827
818 c->operand[i++] = burst; 828 fdtv->avc_data_length = ALIGN(3 + pos, 4);
819 c->operand[i++] = conttone;
820
821 fdtv->avc_data_length = ALIGN(3 + i, 4);
822 ret = avc_write(fdtv); 829 ret = avc_write(fdtv);
823 if (ret < 0) 830 if (ret < 0)
824 goto out; 831 goto out;
@@ -840,8 +847,6 @@ int avc_register_remote_control(struct firedtv *fdtv)
840 847
841 mutex_lock(&fdtv->avc_mutex); 848 mutex_lock(&fdtv->avc_mutex);
842 849
843 memset(c, 0, sizeof(*c));
844
845 c->ctype = AVC_CTYPE_NOTIFY; 850 c->ctype = AVC_CTYPE_NOTIFY;
846 c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; 851 c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
847 c->opcode = AVC_OPCODE_VENDOR; 852 c->opcode = AVC_OPCODE_VENDOR;
@@ -850,6 +855,7 @@ int avc_register_remote_control(struct firedtv *fdtv)
850 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; 855 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
851 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; 856 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
852 c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; 857 c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
858 c->operand[4] = 0; /* padding */
853 859
854 fdtv->avc_data_length = 8; 860 fdtv->avc_data_length = 8;
855 ret = avc_write(fdtv); 861 ret = avc_write(fdtv);
@@ -878,8 +884,6 @@ int avc_tuner_host2ca(struct firedtv *fdtv)
878 884
879 mutex_lock(&fdtv->avc_mutex); 885 mutex_lock(&fdtv->avc_mutex);
880 886
881 memset(c, 0, sizeof(*c));
882
883 c->ctype = AVC_CTYPE_CONTROL; 887 c->ctype = AVC_CTYPE_CONTROL;
884 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 888 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
885 c->opcode = AVC_OPCODE_VENDOR; 889 c->opcode = AVC_OPCODE_VENDOR;
@@ -890,8 +894,7 @@ int avc_tuner_host2ca(struct firedtv *fdtv)
890 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; 894 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
891 c->operand[4] = 0; /* slot */ 895 c->operand[4] = 0; /* slot */
892 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 896 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
893 c->operand[6] = 0; /* more/last */ 897 clear_operands(c, 6, 8);
894 c->operand[7] = 0; /* length */
895 898
896 fdtv->avc_data_length = 12; 899 fdtv->avc_data_length = 12;
897 ret = avc_write(fdtv); 900 ret = avc_write(fdtv);
@@ -937,8 +940,6 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
937 940
938 mutex_lock(&fdtv->avc_mutex); 941 mutex_lock(&fdtv->avc_mutex);
939 942
940 memset(c, 0, sizeof(*c));
941
942 c->ctype = AVC_CTYPE_STATUS; 943 c->ctype = AVC_CTYPE_STATUS;
943 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 944 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
944 c->opcode = AVC_OPCODE_VENDOR; 945 c->opcode = AVC_OPCODE_VENDOR;
@@ -949,6 +950,7 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
949 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 950 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
950 c->operand[4] = 0; /* slot */ 951 c->operand[4] = 0; /* slot */
951 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 952 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
953 clear_operands(c, 6, LAST_OPERAND);
952 954
953 fdtv->avc_data_length = 12; 955 fdtv->avc_data_length = 12;
954 ret = avc_write(fdtv); 956 ret = avc_write(fdtv);
@@ -979,8 +981,6 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
979 981
980 mutex_lock(&fdtv->avc_mutex); 982 mutex_lock(&fdtv->avc_mutex);
981 983
982 memset(c, 0, sizeof(*c));
983
984 c->ctype = AVC_CTYPE_STATUS; 984 c->ctype = AVC_CTYPE_STATUS;
985 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 985 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
986 c->opcode = AVC_OPCODE_VENDOR; 986 c->opcode = AVC_OPCODE_VENDOR;
@@ -991,6 +991,7 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
991 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 991 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
992 c->operand[4] = 0; /* slot */ 992 c->operand[4] = 0; /* slot */
993 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 993 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
994 clear_operands(c, 6, LAST_OPERAND);
994 995
995 fdtv->avc_data_length = 12; 996 fdtv->avc_data_length = 12;
996 ret = avc_write(fdtv); 997 ret = avc_write(fdtv);
@@ -1020,8 +1021,6 @@ int avc_ca_reset(struct firedtv *fdtv)
1020 1021
1021 mutex_lock(&fdtv->avc_mutex); 1022 mutex_lock(&fdtv->avc_mutex);
1022 1023
1023 memset(c, 0, sizeof(*c));
1024
1025 c->ctype = AVC_CTYPE_CONTROL; 1024 c->ctype = AVC_CTYPE_CONTROL;
1026 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1025 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1027 c->opcode = AVC_OPCODE_VENDOR; 1026 c->opcode = AVC_OPCODE_VENDOR;
@@ -1064,8 +1063,6 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1064 1063
1065 mutex_lock(&fdtv->avc_mutex); 1064 mutex_lock(&fdtv->avc_mutex);
1066 1065
1067 memset(c, 0, sizeof(*c));
1068
1069 c->ctype = AVC_CTYPE_CONTROL; 1066 c->ctype = AVC_CTYPE_CONTROL;
1070 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1067 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1071 c->opcode = AVC_OPCODE_VENDOR; 1068 c->opcode = AVC_OPCODE_VENDOR;
@@ -1096,7 +1093,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1096 1093
1097 c->operand[12] = 0x02; /* Table id=2 */ 1094 c->operand[12] = 0x02; /* Table id=2 */
1098 c->operand[13] = 0x80; /* Section syntax + length */ 1095 c->operand[13] = 0x80; /* Section syntax + length */
1099 /* c->operand[14] = XXXprogram_info_length + 12; */ 1096
1100 c->operand[15] = msg[1]; /* Program number */ 1097 c->operand[15] = msg[1]; /* Program number */
1101 c->operand[16] = msg[2]; 1098 c->operand[16] = msg[2];
1102 c->operand[17] = 0x01; /* Version number=0 + current/next=1 */ 1099 c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
@@ -1144,12 +1141,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1144 write_pos += es_info_length; 1141 write_pos += es_info_length;
1145 } 1142 }
1146 } 1143 }
1147 1144 write_pos += 4; /* CRC */
1148 /* CRC */
1149 c->operand[write_pos++] = 0x00;
1150 c->operand[write_pos++] = 0x00;
1151 c->operand[write_pos++] = 0x00;
1152 c->operand[write_pos++] = 0x00;
1153 1145
1154 c->operand[7] = 0x82; 1146 c->operand[7] = 0x82;
1155 c->operand[8] = (write_pos - 10) >> 8; 1147 c->operand[8] = (write_pos - 10) >> 8;
@@ -1161,6 +1153,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1161 c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; 1153 c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
1162 c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; 1154 c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
1163 c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; 1155 c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
1156 pad_operands(c, write_pos);
1164 1157
1165 fdtv->avc_data_length = ALIGN(3 + write_pos, 4); 1158 fdtv->avc_data_length = ALIGN(3 + write_pos, 4);
1166 ret = avc_write(fdtv); 1159 ret = avc_write(fdtv);
@@ -1186,8 +1179,6 @@ int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
1186 1179
1187 mutex_lock(&fdtv->avc_mutex); 1180 mutex_lock(&fdtv->avc_mutex);
1188 1181
1189 memset(c, 0, sizeof(*c));
1190
1191 c->ctype = AVC_CTYPE_STATUS; 1182 c->ctype = AVC_CTYPE_STATUS;
1192 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1183 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1193 c->opcode = AVC_OPCODE_VENDOR; 1184 c->opcode = AVC_OPCODE_VENDOR;
@@ -1198,8 +1189,7 @@ int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
1198 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 1189 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1199 c->operand[4] = 0; /* slot */ 1190 c->operand[4] = 0; /* slot */
1200 c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ 1191 c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
1201 c->operand[6] = 0; /* more/last */ 1192 clear_operands(c, 6, LAST_OPERAND);
1202 c->operand[7] = 0; /* length */
1203 1193
1204 fdtv->avc_data_length = 12; 1194 fdtv->avc_data_length = 12;
1205 ret = avc_write(fdtv); 1195 ret = avc_write(fdtv);
@@ -1222,8 +1212,6 @@ int avc_ca_enter_menu(struct firedtv *fdtv)
1222 1212
1223 mutex_lock(&fdtv->avc_mutex); 1213 mutex_lock(&fdtv->avc_mutex);
1224 1214
1225 memset(c, 0, sizeof(*c));
1226
1227 c->ctype = AVC_CTYPE_STATUS; 1215 c->ctype = AVC_CTYPE_STATUS;
1228 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1216 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1229 c->opcode = AVC_OPCODE_VENDOR; 1217 c->opcode = AVC_OPCODE_VENDOR;
@@ -1234,8 +1222,7 @@ int avc_ca_enter_menu(struct firedtv *fdtv)
1234 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; 1222 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
1235 c->operand[4] = 0; /* slot */ 1223 c->operand[4] = 0; /* slot */
1236 c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; 1224 c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
1237 c->operand[6] = 0; /* more/last */ 1225 clear_operands(c, 6, 8);
1238 c->operand[7] = 0; /* length */
1239 1226
1240 fdtv->avc_data_length = 12; 1227 fdtv->avc_data_length = 12;
1241 ret = avc_write(fdtv); 1228 ret = avc_write(fdtv);
@@ -1255,8 +1242,6 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1255 1242
1256 mutex_lock(&fdtv->avc_mutex); 1243 mutex_lock(&fdtv->avc_mutex);
1257 1244
1258 memset(c, 0, sizeof(*c));
1259
1260 c->ctype = AVC_CTYPE_STATUS; 1245 c->ctype = AVC_CTYPE_STATUS;
1261 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1246 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
1262 c->opcode = AVC_OPCODE_VENDOR; 1247 c->opcode = AVC_OPCODE_VENDOR;
@@ -1267,8 +1252,7 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1267 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 1252 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1268 c->operand[4] = 0; /* slot */ 1253 c->operand[4] = 0; /* slot */
1269 c->operand[5] = SFE_VENDOR_TAG_CA_MMI; 1254 c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
1270 c->operand[6] = 0; /* more/last */ 1255 clear_operands(c, 6, LAST_OPERAND);
1271 c->operand[7] = 0; /* length */
1272 1256
1273 fdtv->avc_data_length = 12; 1257 fdtv->avc_data_length = 12;
1274 ret = avc_write(fdtv); 1258 ret = avc_write(fdtv);
>*dns; struct sctp_cookie_param *cookie; struct sctp_supported_addrs_param *sat; struct sctp_ipv4addr_param *v4; struct sctp_ipv6addr_param *v6; union sctp_addr_param *addr; struct sctp_adaption_ind_param *aind; }; /* RFC 2960. Section 3.3.5 Heartbeat. * Heartbeat Information: variable length * The Sender-specific Heartbeat Info field should normally include * information about the sender's current time when this HEARTBEAT * chunk is sent and the destination transport address to which this * HEARTBEAT is sent (see Section 8.3). */ typedef struct sctp_sender_hb_info { struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; } __attribute__((packed)) sctp_sender_hb_info_t; /* * RFC 2960 1.3.2 Sequenced Delivery within Streams * * The term "stream" is used in SCTP to refer to a sequence of user * messages that are to be delivered to the upper-layer protocol in * order with respect to other messages within the same stream. This is * in contrast to its usage in TCP, where it refers to a sequence of * bytes (in this document a byte is assumed to be eight bits). * ... * * This is the structure we use to track both our outbound and inbound * SSN, or Stream Sequence Numbers. */ struct sctp_stream { __u16 *ssn; unsigned int len; }; struct sctp_ssnmap { struct sctp_stream in; struct sctp_stream out; int malloced; }; struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, gfp_t gfp); void sctp_ssnmap_free(struct sctp_ssnmap *map); void sctp_ssnmap_clear(struct sctp_ssnmap *map); /* What is the current SSN number for this stream? */ static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id) { return stream->ssn[id]; } /* Return the next SSN number for this stream. */ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id) { return stream->ssn[id]++; } /* Skip over this ssn and all below. */ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, __u16 ssn) { stream->ssn[id] = ssn+1; } /* * Pointers to address related SCTP functions. * (i.e. things that depend on the address family.) */ struct sctp_af { int (*sctp_xmit) (struct sk_buff *skb, struct sctp_transport *, int ipfragok); int (*setsockopt) (struct sock *sk, int level, int optname, char __user *optval, int optlen); int (*getsockopt) (struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); int (*compat_setsockopt) (struct sock *sk, int level, int optname, char __user *optval, int optlen); int (*compat_getsockopt) (struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); struct dst_entry *(*get_dst) (struct sctp_association *asoc, union sctp_addr *daddr, union sctp_addr *saddr); void (*get_saddr) (struct sctp_association *asoc, struct dst_entry *dst, union sctp_addr *daddr, union sctp_addr *saddr); void (*copy_addrlist) (struct list_head *, struct net_device *); void (*dst_saddr) (union sctp_addr *saddr, struct dst_entry *dst, unsigned short port); int (*cmp_addr) (const union sctp_addr *addr1, const union sctp_addr *addr2); void (*addr_copy) (union sctp_addr *dst, union sctp_addr *src); void (*from_skb) (union sctp_addr *, struct sk_buff *skb, int saddr); void (*from_sk) (union sctp_addr *, struct sock *sk); void (*to_sk_saddr) (union sctp_addr *, struct sock *sk); void (*to_sk_daddr) (union sctp_addr *, struct sock *sk); void (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, __u16 port, int iif); int (*to_addr_param) (const union sctp_addr *, union sctp_addr_param *); int (*addr_valid) (union sctp_addr *, struct sctp_sock *); sctp_scope_t (*scope) (union sctp_addr *); void (*inaddr_any) (union sctp_addr *, unsigned short); int (*is_any) (const union sctp_addr *); int (*available) (union sctp_addr *, struct sctp_sock *); int (*skb_iif) (const struct sk_buff *sk); int (*is_ce) (const struct sk_buff *sk); void (*seq_dump_addr)(struct seq_file *seq, union sctp_addr *addr); __u16 net_header_len; int sockaddr_len; sa_family_t sa_family; struct list_head list; }; struct sctp_af *sctp_get_af_specific(sa_family_t); int sctp_register_af(struct sctp_af *); /* Protocol family functions. */ struct sctp_pf { void (*event_msgname)(struct sctp_ulpevent *, char *, int *); void (*skb_msgname) (struct sk_buff *, char *, int *); int (*af_supported) (sa_family_t, struct sctp_sock *); int (*cmp_addr) (const union sctp_addr *, const union sctp_addr *, struct sctp_sock *); int (*bind_verify) (struct sctp_sock *, union sctp_addr *); int (*send_verify) (struct sctp_sock *, union sctp_addr *); int (*supported_addrs)(const struct sctp_sock *, __u16 *); struct sock *(*create_accept_sk) (struct sock *sk, struct sctp_association *asoc); void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); struct sctp_af *af; }; /* Structure to track chunk fragments that have been acked, but peer * fragments of the same message have not. */ struct sctp_datamsg { /* Chunks waiting to be submitted to lower layer. */ struct list_head chunks; /* Chunks that have been transmitted. */ struct list_head track; /* Reference counting. */ atomic_t refcnt; /* When is this message no longer interesting to the peer? */ unsigned long expires_at; /* Did the messenge fail to send? */ int send_error; char send_failed; /* Control whether chunks from this message can be abandoned. */ char can_abandon; }; struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, struct sctp_sndrcvinfo *, struct msghdr *, int len); void sctp_datamsg_put(struct sctp_datamsg *); void sctp_datamsg_free(struct sctp_datamsg *); void sctp_datamsg_track(struct sctp_chunk *); void sctp_chunk_fail(struct sctp_chunk *, int error); int sctp_chunk_abandoned(struct sctp_chunk *); /* RFC2960 1.4 Key Terms * * o Chunk: A unit of information within an SCTP packet, consisting of * a chunk header and chunk-specific content. * * As a matter of convenience, we remember the SCTP common header for * each chunk as well as a few other header pointers... */ struct sctp_chunk { struct list_head list; atomic_t refcnt; /* This is our link to the per-transport transmitted list. */ struct list_head transmitted_list; /* This field is used by chunks that hold fragmented data. * For the first fragment this is the list that holds the rest of * fragments. For the remaining fragments, this is the link to the * frag_list maintained in the first fragment. */ struct list_head frag_list; /* This points to the sk_buff containing the actual data. */ struct sk_buff *skb; /* These are the SCTP headers by reverse order in a packet. * Note that some of these may happen more than once. In that * case, we point at the "current" one, whatever that means * for that level of header. */ /* We point this at the FIRST TLV parameter to chunk_hdr. */ union sctp_params param_hdr; union { __u8 *v; struct sctp_datahdr *data_hdr; struct sctp_inithdr *init_hdr; struct sctp_sackhdr *sack_hdr; struct sctp_heartbeathdr *hb_hdr; struct sctp_sender_hb_info *hbs_hdr; struct sctp_shutdownhdr *shutdown_hdr; struct sctp_signed_cookie *cookie_hdr; struct sctp_ecnehdr *ecne_hdr; struct sctp_cwrhdr *ecn_cwr_hdr; struct sctp_errhdr *err_hdr; struct sctp_addiphdr *addip_hdr; struct sctp_fwdtsn_hdr *fwdtsn_hdr; } subh; __u8 *chunk_end; struct sctp_chunkhdr *chunk_hdr; struct sctphdr *sctp_hdr; /* This needs to be recoverable for SCTP_SEND_FAILED events. */ struct sctp_sndrcvinfo sinfo; /* Which association does this belong to? */ struct sctp_association *asoc; /* What endpoint received this chunk? */ struct sctp_ep_common *rcvr; /* We fill this in if we are calculating RTT. */ unsigned long sent_at; /* What is the origin IP address for this chunk? */ union sctp_addr source; /* Destination address for this chunk. */ union sctp_addr dest; /* For outbound message, track all fragments for SEND_FAILED. */ struct sctp_datamsg *msg; /* For an inbound chunk, this tells us where it came from. * For an outbound chunk, it tells us where we'd like it to * go. It is NULL if we have no preference. */ struct sctp_transport *transport; __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */ __u8 resent; /* Has this chunk ever been retransmitted. */ __u8 has_tsn; /* Does this chunk have a TSN yet? */ __u8 has_ssn; /* Does this chunk have a SSN yet? */ __u8 singleton; /* Was this the only chunk in the packet? */ __u8 end_of_packet; /* Was this the last chunk in the packet? */ __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ __u8 pdiscard; /* Discard the whole packet now? */ __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ __u8 tsn_missing_report; /* Data chunk missing counter. */ __u8 data_accepted; /* At least 1 chunk in this packet accepted */ }; void sctp_chunk_hold(struct sctp_chunk *); void sctp_chunk_put(struct sctp_chunk *); int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, struct iovec *data); void sctp_chunk_free(struct sctp_chunk *); void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); struct sctp_chunk *sctp_chunkify(struct sk_buff *, const struct sctp_association *, struct sock *); void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, union sctp_addr *); const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); /* This is a structure for holding either an IPv6 or an IPv4 address. */ /* sin_family -- AF_INET or AF_INET6 * sin_port -- ordinary port number * sin_addr -- cast to either (struct in_addr) or (struct in6_addr) */ struct sctp_sockaddr_entry { struct list_head list; union sctp_addr a; }; typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); /* This structure holds lists of chunks as we are assembling for * transmission. */ struct sctp_packet { /* These are the SCTP header values (host order) for the packet. */ __u16 source_port; __u16 destination_port; __u32 vtag; /* This contains the payload chunks. */ struct list_head chunk_list; /* This is the overhead of the sctp and ip headers. */ size_t overhead; /* This is the total size of all chunks INCLUDING padding. */ size_t size; /* The packet is destined for this transport address. * The function we finally use to pass down to the next lower * layer lives in the transport structure. */ struct sctp_transport *transport; /* This packet contains a COOKIE-ECHO chunk. */ char has_cookie_echo; /* This packet containsa SACK chunk. */ char has_sack; /* SCTP cannot fragment this packet. So let ip fragment it. */ char ipfragok; int malloced; }; struct sctp_packet *sctp_packet_init(struct sctp_packet *, struct sctp_transport *, __u16 sport, __u16 dport); struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int); sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, struct sctp_chunk *); sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, struct sctp_chunk *); int sctp_packet_transmit(struct sctp_packet *); void sctp_packet_free(struct sctp_packet *); static inline int sctp_packet_empty(struct sctp_packet *packet) { return (packet->size == packet->overhead); } /* This represents a remote transport address. * For local transport addresses, we just use union sctp_addr. * * RFC2960 Section 1.4 Key Terms * * o Transport address: A Transport Address is traditionally defined * by Network Layer address, Transport Layer protocol and Transport * Layer port number. In the case of SCTP running over IP, a * transport address is defined by the combination of an IP address * and an SCTP port number (where SCTP is the Transport protocol). * * RFC2960 Section 7.1 SCTP Differences from TCP Congestion control * * o The sender keeps a separate congestion control parameter set for * each of the destination addresses it can send to (not each * source-destination pair but for each destination). The parameters * should decay if the address is not used for a long enough time * period. * */ struct sctp_transport { /* A list of transports. */ struct list_head transports; /* Reference counting. */ atomic_t refcnt; int dead; /* This is the peer's IP address and port. */ union sctp_addr ipaddr; /* These are the functions we call to handle LLP stuff. */ struct sctp_af *af_specific; /* Which association do we belong to? */ struct sctp_association *asoc; /* RFC2960 * * 12.3 Per Transport Address Data * * For each destination transport address in the peer's * address list derived from the INIT or INIT ACK chunk, a * number of data elements needs to be maintained including: */ __u32 rtt; /* This is the most recent RTT. */ /* RTO : The current retransmission timeout value. */ unsigned long rto; /* RTTVAR : The current RTT variation. */ __u32 rttvar; /* SRTT : The current smoothed round trip time. */ __u32 srtt; /* RTO-Pending : A flag used to track if one of the DATA * chunks sent to this address is currently being * used to compute a RTT. If this flag is 0, * the next DATA chunk sent to this destination * should be used to compute a RTT and this flag * should be set. Every time the RTT * calculation completes (i.e. the DATA chunk * is SACK'd) clear this flag. */ int rto_pending; /* * These are the congestion stats. */ /* cwnd : The current congestion window. */ __u32 cwnd; /* This is the actual cwnd. */ /* ssthresh : The current slow start threshold value. */ __u32 ssthresh; /* partial : The tracking method for increase of cwnd when in * bytes acked : congestion avoidance mode (see Section 6.2.2) */ __u32 partial_bytes_acked; /* Data that has been sent, but not acknowledged. */ __u32 flight_size; /* Destination */ struct dst_entry *dst; /* Source address. */ union sctp_addr saddr; /* When was the last time(in jiffies) that a data packet was sent on * this transport? This is used to adjust the cwnd when the transport * becomes inactive. */ unsigned long last_time_used; /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to * the destination address every heartbeat interval. */ unsigned long hbinterval; /* SACK delay timeout */ unsigned long sackdelay; /* When was the last time (in jiffies) that we heard from this * transport? We use this to pick new active and retran paths. */ unsigned long last_time_heard; /* Last time(in jiffies) when cwnd is reduced due to the congestion * indication based on ECNE chunk. */ unsigned long last_time_ecne_reduced; /* This is the max_retrans value for the transport and will * be initialized from the assocs value. This can be changed * using SCTP_SET_PEER_ADDR_PARAMS socket option. */ __u16 pathmaxrxt; /* PMTU : The current known path MTU. */ __u32 pathmtu; /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* The number of times INIT has been sent on this transport. */ int init_sent_count; /* state : The current state of this destination, * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN. */ int state; /* These are the error stats for this destination. */ /* Error count : The current error count for this destination. */ unsigned short error_count; /* Per : A timer used by each destination. * Destination : * Timer : * * [Everywhere else in the text this is called T3-rtx. -ed] */ struct timer_list T3_rtx_timer; /* Heartbeat timer is per destination. */ struct timer_list hb_timer; /* Since we're using per-destination retransmission timers * (see above), we're also using per-destination "transmitted" * queues. This probably ought to be a private struct * accessible only within the outqueue, but it's not, yet. */ struct list_head transmitted; /* We build bundle-able packets for this transport here. */ struct sctp_packet packet; /* This is the list of transports that have chunks to send. */ struct list_head send_ready; int malloced; /* Is this structure kfree()able? */ /* State information saved for SFR_CACC algorithm. The key * idea in SFR_CACC is to maintain state at the sender on a * per-destination basis when a changeover happens. * char changeover_active; * char cycling_changeover; * __u32 next_tsn_at_change; * char cacc_saw_newack; */ struct { /* An unsigned integer, which stores the next TSN to be * used by the sender, at the moment of changeover. */ __u32 next_tsn_at_change; /* A flag which indicates the occurrence of a changeover */ char changeover_active; /* A flag which indicates whether the change of primary is * the first switch to this destination address during an * active switch. */ char cycling_changeover; /* A temporary flag, which is used during the processing of * a SACK to estimate the causative TSN(s)'s group. */ char cacc_saw_newack; } cacc; }; struct sctp_transport *sctp_transport_new(const union sctp_addr *, gfp_t); void sctp_transport_set_owner(struct sctp_transport *, struct sctp_association *); void sctp_transport_route(struct sctp_transport *, union sctp_addr *, struct sctp_sock *); void sctp_transport_pmtu(struct sctp_transport *); void sctp_transport_free(struct sctp_transport *); void sctp_transport_reset_timers(struct sctp_transport *); void sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); unsigned long sctp_transport_timeout(struct sctp_transport *); /* This is the structure we use to queue packets as they come into * SCTP. We write packets to it and read chunks from it. */ struct sctp_inq { /* This is actually a queue of sctp_chunk each * containing a partially decoded packet. */ struct list_head in_chunk_list; /* This is the packet which is currently off the in queue and is * being worked on through the inbound chunk processing. */ struct sctp_chunk *in_progress; /* This is the delayed task to finish delivering inbound * messages. */ struct work_struct immediate; int malloced; /* Is this structure kfree()able? */ }; void sctp_inq_init(struct sctp_inq *); void sctp_inq_free(struct sctp_inq *); void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *); /* This is the structure we use to hold outbound chunks. You push * chunks in and they automatically pop out the other end as bundled * packets (it calls (*output_handler)()). * * This structure covers sections 6.3, 6.4, 6.7, 6.8, 6.10, 7., 8.1, * and 8.2 of the v13 draft. * * It handles retransmissions. The connection to the timeout portion * of the state machine is through sctp_..._timeout() and timeout_handler. * * If you feed it SACKs, it will eat them. * * If you give it big chunks, it will fragment them. * * It assigns TSN's to data chunks. This happens at the last possible * instant before transmission. * * When free()'d, it empties itself out via output_handler(). */ struct sctp_outq { struct sctp_association *asoc; /* Data pending that has never been transmitted. */ struct list_head out_chunk_list; unsigned out_qlen; /* Total length of queued data chunks. */ /* Error of send failed, may used in SCTP_SEND_FAILED event. */ unsigned error; /* These are control chunks we want to send. */ struct list_head control_chunk_list; /* These are chunks that have been sacked but are above the * CTSN, or cumulative tsn ack point. */ struct list_head sacked; /* Put chunks on this list to schedule them for * retransmission. */ struct list_head retransmit; /* Put chunks on this list to save them for FWD TSN processing as * they were abandoned. */ struct list_head abandoned; /* How many unackd bytes do we have in-flight? */ __u32 outstanding_bytes; /* Corked? */ char cork; /* Is this structure empty? */ char empty; /* Are we kfree()able? */ char malloced; }; void sctp_outq_init(struct sctp_association *, struct sctp_outq *); void sctp_outq_teardown(struct sctp_outq *); void sctp_outq_free(struct sctp_outq*); int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); int sctp_outq_flush(struct sctp_outq *, int); int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_is_empty(const struct sctp_outq *); void sctp_outq_restart(struct sctp_outq *); void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, sctp_retransmit_reason_t); void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8); int sctp_outq_uncork(struct sctp_outq *); /* Uncork and flush an outqueue. */ static inline void sctp_outq_cork(struct sctp_outq *q) { q->cork = 1; } /* These bind address data fields common between endpoints and associations */ struct sctp_bind_addr { /* RFC 2960 12.1 Parameters necessary for the SCTP instance * * SCTP Port: The local SCTP port number the endpoint is * bound to. */ __u16 port; /* RFC 2960 12.1 Parameters necessary for the SCTP instance * * Address List: The list of IP addresses that this instance * has bound. This information is passed to one's * peer(s) in INIT and INIT ACK chunks. */ struct list_head address_list; int malloced; /* Are we kfree()able? */ }; void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port); void sctp_bind_addr_free(struct sctp_bind_addr *); int sctp_bind_addr_copy(struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, sctp_scope_t scope, gfp_t gfp, int flags); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, gfp_t gfp); int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, const union sctp_addr *addrs, int addrcnt, struct sctp_sock *opt); union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, int *addrs_len, gfp_t gfp); int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, __u16 port, gfp_t gfp); sctp_scope_t sctp_scope(const union sctp_addr *); int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope); int sctp_is_any(const union sctp_addr *addr); int sctp_addr_is_valid(const union sctp_addr *addr); /* What type of endpoint? */ typedef enum { SCTP_EP_TYPE_SOCKET, SCTP_EP_TYPE_ASSOCIATION, } sctp_endpoint_type_t; /* * A common base class to bridge the implmentation view of a * socket (usually listening) endpoint versus an association's * local endpoint. * This common structure is useful for several purposes: * 1) Common interface for lookup routines. * a) Subfunctions work for either endpoint or association * b) Single interface to lookup allows hiding the lookup lock rather * than acquiring it externally. * 2) Common interface for the inbound chunk handling/state machine. * 3) Common object handling routines for reference counting, etc. * 4) Disentangle association lookup from endpoint lookup, where we * do not have to find our endpoint to find our association. * */ struct sctp_ep_common { /* Fields to help us manage our entries in the hash tables. */ struct sctp_ep_common *next; struct sctp_ep_common **pprev; int hashent; /* Runtime type information. What kind of endpoint is this? */ sctp_endpoint_type_t type; /* Some fields to help us manage this object. * refcnt - Reference count access to this object. * dead - Do not attempt to use this object. * malloced - Do we need to kfree this object? */ atomic_t refcnt; char dead; char malloced; /* What socket does this endpoint belong to? */ struct sock *sk; /* This is where we receive inbound chunks. */ struct sctp_inq inqueue; /* This substructure includes the defining parameters of the * endpoint: * bind_addr.port is our shared port number. * bind_addr.address_list is our set of local IP addresses. */ struct sctp_bind_addr bind_addr; /* Protection during address list comparisons. */ rwlock_t addr_lock; }; /* RFC Section 1.4 Key Terms * * o SCTP endpoint: The logical sender/receiver of SCTP packets. On a * multi-homed host, an SCTP endpoint is represented to its peers as a * combination of a set of eligible destination transport addresses to * which SCTP packets can be sent and a set of eligible source * transport addresses from which SCTP packets can be received. * All transport addresses used by an SCTP endpoint must use the * same port number, but can use multiple IP addresses. A transport * address used by an SCTP endpoint must not be used by another * SCTP endpoint. In other words, a transport address is unique * to an SCTP endpoint. * * From an implementation perspective, each socket has one of these. * A TCP-style socket will have exactly one association on one of * these. An UDP-style socket will have multiple associations hanging * off one of these. */ struct sctp_endpoint { /* Common substructure for endpoint and association. */ struct sctp_ep_common base; /* Associations: A list of current associations and mappings * to the data consumers for each association. This * may be in the form of a hash table or other * implementation dependent structure. The data * consumers may be process identification * information such as file descriptors, named pipe * pointer, or table pointers dependent on how SCTP * is implemented. */ /* This is really a list of struct sctp_association entries. */ struct list_head asocs; /* Secret Key: A secret key used by this endpoint to compute * the MAC. This SHOULD be a cryptographic quality * random number with a sufficient length. * Discussion in [RFC1750] can be helpful in * selection of the key. */ __u8 secret_key[SCTP_HOW_MANY_SECRETS][SCTP_SECRET_SIZE]; int current_key; int last_key; int key_changed_at; /* digest: This is a digest of the sctp cookie. This field is * only used on the receive path when we try to validate * that the cookie has not been tampered with. We put * this here so we pre-allocate this once and can re-use * on every receive. */ __u8 digest[SCTP_SIGNATURE_SIZE]; /* sendbuf acct. policy. */ __u32 sndbuf_policy; /* rcvbuf acct. policy. */ __u32 rcvbuf_policy; }; /* Recover the outter endpoint structure. */ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base) { struct sctp_endpoint *ep; ep = container_of(base, struct sctp_endpoint, base); return ep; } /* These are function signatures for manipulating endpoints. */ struct sctp_endpoint *sctp_endpoint_new(struct sock *, gfp_t); void sctp_endpoint_free(struct sctp_endpoint *); void sctp_endpoint_put(struct sctp_endpoint *); void sctp_endpoint_hold(struct sctp_endpoint *); void sctp_endpoint_add_asoc(struct sctp_endpoint *, struct sctp_association *); struct sctp_association *sctp_endpoint_lookup_assoc( const struct sctp_endpoint *ep, const union sctp_addr *paddr, struct sctp_transport **); int sctp_endpoint_is_peeled_off(struct sctp_endpoint *, const union sctp_addr *); struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *, const union sctp_addr *); int sctp_has_association(const union sctp_addr *laddr, const union sctp_addr *paddr); int sctp_verify_init(const struct sctp_association *asoc, sctp_cid_t, sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, struct sctp_chunk **err_chunk); int sctp_process_init(struct sctp_association *, sctp_cid_t cid, const union sctp_addr *peer, sctp_init_chunk_t *init, gfp_t gfp); __u32 sctp_generate_tag(const struct sctp_endpoint *); __u32 sctp_generate_tsn(const struct sctp_endpoint *); /* RFC2960 * * 12. Recommended Transmission Control Block (TCB) Parameters * * This section details a recommended set of parameters that should * be contained within the TCB for an implementation. This section is * for illustrative purposes and should not be deemed as requirements * on an implementation or as an exhaustive list of all parameters * inside an SCTP TCB. Each implementation may need its own additional * parameters for optimization. */ /* Here we have information about each individual association. */ struct sctp_association { /* A base structure common to endpoint and association. * In this context, it represents the associations's view * of the local endpoint of the association. */ struct sctp_ep_common base; /* Associations on the same socket. */ struct list_head asocs; /* association id. */ sctp_assoc_t assoc_id; /* This is our parent endpoint. */ struct sctp_endpoint *ep; /* These are those association elements needed in the cookie. */ struct sctp_cookie c; /* This is all information about our peer. */ struct { /* rwnd * * Peer Rwnd : Current calculated value of the peer's rwnd. */ __u32 rwnd; /* transport_addr_list * * Peer : A list of SCTP transport addresses that the * Transport : peer is bound to. This information is derived * Address : from the INIT or INIT ACK and is used to * List : associate an inbound packet with a given * : association. Normally this information is * : hashed or keyed for quick lookup and access * : of the TCB. * : The list is also initialized with the list * : of addresses passed with the sctp_connectx() * : call. * * It is a list of SCTP_transport's. */ struct list_head transport_addr_list; /* transport_count * * Peer : A count of the number of peer addresses * Transport : in the Peer Transport Address List. * Address : * Count : */ __u16 transport_count; /* port * The transport layer port number. */ __u16 port; /* primary_path * * Primary : This is the current primary destination * Path : transport address of the peer endpoint. It * : may also specify a source transport address * : on this endpoint. * * All of these paths live on transport_addr_list. * * At the bakeoffs, we discovered that the intent of * primaryPath is that it only changes when the ULP * asks to have it changed. We add the activePath to * designate the connection we are currently using to * transmit new data and most control chunks. */ struct sctp_transport *primary_path; /* Cache the primary path address here, when we * need a an address for msg_name. */ union sctp_addr primary_addr; /* active_path * The path that we are currently using to * transmit new data and most control chunks. */ struct sctp_transport *active_path; /* retran_path * * RFC2960 6.4 Multi-homed SCTP Endpoints * ... * Furthermore, when its peer is multi-homed, an * endpoint SHOULD try to retransmit a chunk to an * active destination transport address that is * different from the last destination address to * which the DATA chunk was sent. */ struct sctp_transport *retran_path; /* Pointer to last transport I have sent on. */ struct sctp_transport *last_sent_to; /* This is the last transport I have received DATA on. */ struct sctp_transport *last_data_from; /* * Mapping An array of bits or bytes indicating which out of * Array order TSN's have been received (relative to the * Last Rcvd TSN). If no gaps exist, i.e. no out of * order packets have been received, this array * will be set to all zero. This structure may be * in the form of a circular buffer or bit array. * * Last Rcvd : This is the last TSN received in * TSN : sequence. This value is set initially by * : taking the peer's Initial TSN, received in * : the INIT or INIT ACK chunk, and subtracting * : one from it. * * Throughout most of the specification this is called the * "Cumulative TSN ACK Point". In this case, we * ignore the advice in 12.2 in favour of the term * used in the bulk of the text. This value is hidden * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). */ struct sctp_tsnmap tsn_map; __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)]; /* Ack State : This flag indicates if the next received * : packet is to be responded to with a * : SACK. This is initializedto 0. When a packet * : is received it is incremented. If this value * : reaches 2 or more, a SACK is sent and the * : value is reset to 0. Note: This is used only * : when no DATA chunks are received out of * : order. When DATA chunks are out of order, * : SACK's are not delayed (see Section 6). */ __u8 sack_needed; /* Do we need to sack the peer? */ /* These are capabilities which our peer advertised. */ __u8 ecn_capable; /* Can peer do ECN? */ __u8 ipv4_address; /* Peer understands IPv4 addresses? */ __u8 ipv6_address; /* Peer understands IPv6 addresses? */ __u8 hostname_address;/* Peer understands DNS addresses? */ __u8 asconf_capable; /* Does peer support ADDIP? */ __u8 prsctp_capable; /* Can peer do PR-SCTP? */ __u32 adaption_ind; /* Adaption Code point. */ /* This mask is used to disable sending the ASCONF chunk * with specified parameter to peer. */ __u16 addip_disabled_mask; struct sctp_inithdr i; int cookie_len; void *cookie; /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. * C1) ... "Peer-Serial-Number'. This value MUST be initialized to the * Initial TSN Value minus 1 */ __u32 addip_serial; } peer; /* State : A state variable indicating what state the * : association is in, i.e. COOKIE-WAIT, * : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING, * : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT. * * Note: No "CLOSED" state is illustrated since if a * association is "CLOSED" its TCB SHOULD be removed. * * In this implementation we DO have a CLOSED * state which is used during initiation and shutdown. * * State takes values from SCTP_STATE_*. */ sctp_state_t state; /* The cookie life I award for any cookie. */ struct timeval cookie_life; /* Overall : The overall association error count. * Error Count : [Clear this any time I get something.] */ int overall_error_count; /* These are the association's initial, max, and min RTO values. * These values will be initialized by system defaults, but can * be modified via the SCTP_RTOINFO socket option. */ unsigned long rto_initial; unsigned long rto_max; unsigned long rto_min; /* Maximum number of new data packets that can be sent in a burst. */ int max_burst; /* This is the max_retrans value for the association. This value will * be initialized initialized from system defaults, but can be * modified by the SCTP_ASSOCINFO socket option. */ int max_retrans; /* Maximum number of times the endpoint will retransmit INIT */ __u16 max_init_attempts; /* How many times have we resent an INIT? */ __u16 init_retries; /* The largest timeout or RTO value to use in attempting an INIT */ unsigned long max_init_timeo; /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to * the destination address every heartbeat interval. This value * will be inherited by all new transports. */ unsigned long hbinterval; /* This is the max_retrans value for new transports in the * association. */ __u16 pathmaxrxt; /* Association : The smallest PMTU discovered for all of the * PMTU : peer's transport addresses. */ __u32 pathmtu; /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* SACK delay timeout */ unsigned long sackdelay; unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES]; struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; /* Transport to which SHUTDOWN chunk was last sent. */ struct sctp_transport *shutdown_last_sent_to; /* Transport to which INIT chunk was last sent. */ struct sctp_transport *init_last_sent_to; /* Next TSN : The next TSN number to be assigned to a new * : DATA chunk. This is sent in the INIT or INIT * : ACK chunk to the peer and incremented each * : time a DATA chunk is assigned a TSN * : (normally just prior to transmit or during * : fragmentation). */ __u32 next_tsn; /* * Last Rcvd : This is the last TSN received in sequence. This value * TSN : is set initially by taking the peer's Initial TSN, * : received in the INIT or INIT ACK chunk, and * : subtracting one from it. * * Most of RFC 2960 refers to this as the Cumulative TSN Ack Point. */ __u32 ctsn_ack_point; /* PR-SCTP Advanced.Peer.Ack.Point */ __u32 adv_peer_ack_point; /* Highest TSN that is acknowledged by incoming SACKs. */ __u32 highest_sacked; /* The number of unacknowledged data chunks. Reported through * the SCTP_STATUS sockopt. */ __u16 unack_data; /* This is the association's receive buffer space. This value is used * to set a_rwnd field in an INIT or a SACK chunk. */ __u32 rwnd; /* This is the last advertised value of rwnd over a SACK chunk. */ __u32 a_rwnd; /* Number of bytes by which the rwnd has slopped. The rwnd is allowed * to slop over a maximum of the association's frag_point. */ __u32 rwnd_over; /* This is the sndbuf size in use for the association. * This corresponds to the sndbuf size for the association, * as specified in the sk->sndbuf. */ int sndbuf_used; /* This is the amount of memory that this association has allocated * in the receive path at any given time. */ atomic_t rmem_alloc; /* This is the wait queue head for send requests waiting on * the association sndbuf space. */ wait_queue_head_t wait; /* The message size at which SCTP fragmentation will occur. */ __u32 frag_point; /* Counter used to count INIT errors. */ int init_err_counter; /* Count the number of INIT cycles (for doubling timeout). */ int init_cycle; /* Default send parameters. */ __u16 default_stream; __u16 default_flags; __u32 default_ppid; __u32 default_context; __u32 default_timetolive; /* This tracks outbound ssn for a given stream. */ struct sctp_ssnmap *ssnmap; /* All outbound chunks go through this structure. */ struct sctp_outq outqueue; /* A smart pipe that will handle reordering and fragmentation, * as well as handle passing events up to the ULP. */ struct sctp_ulpq ulpq; /* Last TSN that caused an ECNE Chunk to be sent. */ __u32 last_ecne_tsn; /* Last TSN that caused a CWR Chunk to be sent. */ __u32 last_cwr_tsn; /* How many duplicated TSNs have we seen? */ int numduptsns; /* Number of seconds of idle time before an association is closed. * In the association context, this is really used as a boolean * since the real timeout is stored in the timeouts array */ __u32 autoclose; /* These are to support * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses * and Enforcement of Flow and Message Limits" * <draft-ietf-tsvwg-addip-sctp-02.txt> * or "ADDIP" for short. */ /* ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks * * R1) One and only one ASCONF Chunk MAY be in transit and * unacknowledged at any one time. If a sender, after sending * an ASCONF chunk, decides it needs to transfer another * ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk * returns from the previous ASCONF Chunk before sending a * subsequent ASCONF. Note this restriction binds each side, * so at any time two ASCONF may be in-transit on any given * association (one sent from each endpoint). * * [This is our one-and-only-one ASCONF in flight. If we do * not have an ASCONF in flight, this is NULL.] */ struct sctp_chunk *addip_last_asconf; /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. * * IMPLEMENTATION NOTE: As an optimization a receiver may wish * to save the last ASCONF-ACK for some predetermined period * of time and instead of re-processing the ASCONF (with the * same serial number) it may just re-transmit the * ASCONF-ACK. It may wish to use the arrival of a new serial * number to discard the previously saved ASCONF-ACK or any * other means it may choose to expire the saved ASCONF-ACK. * * [This is our saved ASCONF-ACK. We invalidate it when a new * ASCONF serial number arrives.] */ struct sctp_chunk *addip_last_asconf_ack; /* These ASCONF chunks are waiting to be sent. * * These chunaks can't be pushed to outqueue until receiving * ASCONF_ACK for the previous ASCONF indicated by * addip_last_asconf, so as to guarantee that only one ASCONF * is in flight at any time. * * ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks * * In defining the ASCONF Chunk transfer procedures, it is * essential that these transfers MUST NOT cause congestion * within the network. To achieve this, we place these * restrictions on the transfer of ASCONF Chunks: * * R1) One and only one ASCONF Chunk MAY be in transit and * unacknowledged at any one time. If a sender, after sending * an ASCONF chunk, decides it needs to transfer another * ASCONF Chunk, it MUST wait until the ASCONF-ACK Chunk * returns from the previous ASCONF Chunk before sending a * subsequent ASCONF. Note this restriction binds each side, * so at any time two ASCONF may be in-transit on any given * association (one sent from each endpoint). * * * [I really think this is EXACTLY the sort of intelligence * which already resides in sctp_outq. Please move this * queue and its supporting logic down there. --piggy] */ struct list_head addip_chunk_list; /* ADDIP Section 4.1 ASCONF Chunk Procedures * * A2) A serial number should be assigned to the Chunk. The * serial number SHOULD be a monotonically increasing * number. The serial number SHOULD be initialized at * the start of the association to the same value as the * Initial TSN and every time a new ASCONF chunk is created * it is incremented by one after assigning the serial number * to the newly created chunk. * * ADDIP * 3.1.1 Address/Stream Configuration Change Chunk (ASCONF) * * Serial Number : 32 bits (unsigned integer) * * This value represents a Serial Number for the ASCONF * Chunk. The valid range of Serial Number is from 0 to * 4294967295 (2^32 - 1). Serial Numbers wrap back to 0 * after reaching 4294967295. */ __u32 addip_serial; /* Need to send an ECNE Chunk? */ char need_ecne; /* Is it a temporary association? */ char temp; }; /* An eyecatcher for determining if we are really looking at an * association data structure. */ enum { SCTP_ASSOC_EYECATCHER = 0xa550c123, }; /* Recover the outter association structure. */ static inline struct sctp_association *sctp_assoc(struct sctp_ep_common *base) { struct sctp_association *asoc; asoc = container_of(base, struct sctp_association, base); return asoc; } /* These are function signatures for manipulating associations. */ struct sctp_association * sctp_association_new(const struct sctp_endpoint *, const struct sock *, sctp_scope_t scope, gfp_t gfp); void sctp_association_free(struct sctp_association *); void sctp_association_put(struct sctp_association *); void sctp_association_hold(struct sctp_association *); struct sctp_transport *sctp_assoc_choose_init_transport( struct sctp_association *); struct sctp_transport *sctp_assoc_choose_shutdown_transport( struct sctp_association *); void sctp_assoc_update_retran_path(struct sctp_association *); struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *, const union sctp_addr *); int sctp_assoc_lookup_laddr(struct sctp_association *asoc, const union sctp_addr *laddr); struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *, const union sctp_addr *address, const gfp_t gfp, const int peer_state); void sctp_assoc_del_peer(struct sctp_association *asoc, const union sctp_addr *addr); void sctp_assoc_rm_peer(struct sctp_association *asoc, struct sctp_transport *peer); void sctp_assoc_control_transport(struct sctp_association *, struct sctp_transport *, sctp_transport_cmd_t, sctp_sn_error_t); struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *, __u32); struct sctp_transport *sctp_assoc_is_match(struct sctp_association *, const union sctp_addr *, const union sctp_addr *); void sctp_assoc_migrate(struct sctp_association *, struct sock *); void sctp_assoc_update(struct sctp_association *old, struct sctp_association *new); __u32 sctp_association_get_next_tsn(struct sctp_association *); void sctp_assoc_sync_pmtu(struct sctp_association *); void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned); void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned); void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, gfp_t); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, struct sctp_cookie*, gfp_t gfp); int sctp_cmp_addr_exact(const union sctp_addr *ss1, const union sctp_addr *ss2); struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); /* A convenience structure to parse out SCTP specific CMSGs. */ typedef struct sctp_cmsgs { struct sctp_initmsg *init; struct sctp_sndrcvinfo *info; } sctp_cmsgs_t; /* Structure for tracking memory objects */ typedef struct { char *label; atomic_t *counter; } sctp_dbg_objcnt_entry_t; #endif /* __sctp_structs_h__ */